diff --git a/.env.production b/.env.production
index f8a939f..4577712 100644
--- a/.env.production
+++ b/.env.production
@@ -1,5 +1,5 @@
-REACT_APP_BROKER_URL=https://test.owlbear.rodeo
-REACT_APP_ICE_SERVERS_URL=https://test.owlbear.rodeo/iceservers
+REACT_APP_BROKER_URL=https://connect.owlbear.rodeo
+REACT_APP_ICE_SERVERS_URL=https://connect.owlbear.rodeo/iceservers
REACT_APP_STRIPE_API_KEY=pk_live_MJjzi5djj524Y7h3fL5PNh4e00a852XD51
REACT_APP_STRIPE_URL=https://payment.owlbear.rodeo
REACT_APP_VERSION=$npm_package_version
diff --git a/src/docs/faq/connection.md b/src/docs/faq/connection.md
new file mode 100644
index 0000000..7fa5d0b
--- /dev/null
+++ b/src/docs/faq/connection.md
@@ -0,0 +1,7 @@
+## Connection
+
+---
+
+### WebRTC not supported.
+
+If you see a WebRTC not supported message ensure you are using a browser that supports [WebRTC](https://caniuse.com/rtcpeerconnection) and also ensure that you don't have an extension that is blocking WebRTC connections. Some VPN extensions can cause this.
diff --git a/src/docs/faq/maps.md b/src/docs/faq/maps.md
index 6194ff7..d6e35e5 100644
--- a/src/docs/faq/maps.md
+++ b/src/docs/faq/maps.md
@@ -2,15 +2,15 @@
---
-### I’ve added a map to my game, why can’t my players see it?
+### I’ve added a map to my game, why can’t my players see it?
This could be because it’s taking a while to upload. Ensure that your players can see a loading bar at the top of the site. Owlbear Rodeo will do its best to load a lower quality map, before continuing to load in higher quality. See 'How big can my maps be?' in our faqs.
-If your players do not see a loading bar at the top of their screen ensure that you don't have an extension that is blocking WebRTC connections. Some VPN extensions can causes this.
+If your players do not see a loading bar at the top of their screen ensure that you don't have an extension that is blocking WebRTC connections. Some VPN extensions can cause this.
### Why do some of my tokens have a question mark on them?
-This means that the token hasn’t loaded in just yet. If they still haven’t loaded in after some time, try giving the page a refresh. You should see load progress on the loading bar at the top of the website.
+This means that the token hasn’t loaded in just yet. If they still haven’t loaded in after some time, try giving the page a refresh. You should see load progress on the loading bar at the top of the website.
### How big can my maps be?
@@ -18,7 +18,7 @@ Owlbear Rodeo doesn't impose a limit on map sizes but keep in mind the larger th
### Where are my maps stored?
-Your maps are stored on your local device. This means that clearing your site data will delete your maps, so please only do so if you have no other options.
+Your maps are stored on your local device. This means that clearing your site data will delete your maps, so please only do so if you have no other options.
### Why am I being prompted for a password when I didn't set one?
@@ -30,4 +30,4 @@ We encourage users to create games every 24hrs. Any maps you have added or made
### I can join my game but the spinner is constantly loading, why?
-This could mean that the service is currently down. Please visit us on Twitter or Reddit and let us know.
\ No newline at end of file
+This could mean that the service is currently down. Please visit us on Twitter or Reddit and let us know.
diff --git a/src/docs/releaseNotes/v1.7.0.md b/src/docs/releaseNotes/v1.7.0.md
index bd9ef33..6b89316 100644
--- a/src/docs/releaseNotes/v1.7.0.md
+++ b/src/docs/releaseNotes/v1.7.0.md
@@ -56,6 +56,10 @@ In this update the fog tool has been changed to hopefully help work better with
- Fixed a bug causing the colour of the glass and gemstone dice to be wrong.
- Fixed a bug that would cause custom tokens to not load until a refresh.
+[Reddit](https://www.reddit.com/r/OwlbearRodeo/comments/l15n7n/beta_v170_release_notes_fog_enhancements/)
+[Twitter](https://twitter.com/OwlbearRodeo/status/1351819654113554434)
+[Patreon](https://www.patreon.com/posts/v1-7-0-released-46437122)
+
---
Jan 20 2021
diff --git a/src/helpers/drawing.js b/src/helpers/drawing.js
index 69853b2..4731f4e 100644
--- a/src/helpers/drawing.js
+++ b/src/helpers/drawing.js
@@ -208,6 +208,9 @@ export function drawActionsToShapes(actions, actionIndex) {
let shapesById = {};
for (let i = 0; i <= actionIndex; i++) {
const action = actions[i];
+ if (!action) {
+ continue;
+ }
if (action.type === "add" || action.type === "edit") {
for (let shape of action.shapes) {
shapesById[shape.id] = shape;
diff --git a/src/helpers/useNetworkedState.js b/src/helpers/useNetworkedState.js
index df3e7f7..6f93308 100644
--- a/src/helpers/useNetworkedState.js
+++ b/src/helpers/useNetworkedState.js
@@ -88,7 +88,7 @@ function useNetworkedState(
function handleSocketUpdateEvent(update) {
_setState((prevState) => {
- if (prevState[partialUpdatesKey] === update.id) {
+ if (prevState && prevState[partialUpdatesKey] === update.id) {
let newState = { ...prevState };
applyChanges(newState, update.changes);
lastSyncedStateRef.current = newState;
diff --git a/src/index.js b/src/index.js
index a503ace..8a7a4ad 100644
--- a/src/index.js
+++ b/src/index.js
@@ -25,6 +25,7 @@ if (process.env.REACT_APP_LOGGING === "true") {
"QuotaExceededError",
"XDR encoding failure",
"Assertion failed: Input argument is not an HTMLInputElement",
+ "ERR_WEBRTC_SUPPORT",
],
});
}
diff --git a/src/network/NetworkedMapAndTokens.js b/src/network/NetworkedMapAndTokens.js
index 8d39b50..a27ee9c 100644
--- a/src/network/NetworkedMapAndTokens.js
+++ b/src/network/NetworkedMapAndTokens.js
@@ -50,7 +50,7 @@ function NetworkedMapAndTokens({ session }) {
"mapId"
);
const [assetManifest, setAssetManifest] = useNetworkedState(
- [],
+ null,
session,
"manifest",
100,
@@ -94,15 +94,17 @@ function NetworkedMapAndTokens({ session }) {
function addAssetIfNeeded(asset) {
// Asset needs updating
- const exists = assetManifest.some((oldAsset) =>
+ const exists = assetManifest?.some((oldAsset) =>
compareAssets(oldAsset, asset)
);
- const needsUpdate = assetManifest.some((oldAsset) =>
+ const needsUpdate = assetManifest?.some((oldAsset) =>
assetNeedsUpdate(oldAsset, asset)
);
if (!exists || needsUpdate) {
setAssetManifest((prevAssets) => [
- ...prevAssets.filter((prevAsset) => !compareAssets(prevAsset, asset)),
+ ...(prevAssets || []).filter(
+ (prevAsset) => !compareAssets(prevAsset, asset)
+ ),
asset,
]);
}
@@ -273,6 +275,9 @@ function NetworkedMapAndTokens({ session }) {
*/
async function handleMapTokenStateCreate(tokenState) {
+ if (!currentMap || !currentMapState) {
+ return;
+ }
// If file type token send the token to the other peers
const token = getToken(tokenState.tokenId);
if (token && token.type === "file") {
@@ -283,7 +288,7 @@ function NetworkedMapAndTokens({ session }) {
}
function handleMapTokenStateChange(change) {
- if (currentMapState === null) {
+ if (!currentMapState) {
return;
}
setCurrentMapState((prevMapState) => ({
diff --git a/src/network/Session.js b/src/network/Session.js
index e38ea6e..d8c941c 100644
--- a/src/network/Session.js
+++ b/src/network/Session.js
@@ -119,7 +119,9 @@ class Session extends EventEmitter {
*/
sendTo(sessionId, eventId, data, channel) {
if (!(sessionId in this.peers)) {
- this._addPeer(sessionId, true);
+ if (!this._addPeer(sessionId, true)) {
+ return;
+ }
}
if (!this.peers[sessionId].ready) {
@@ -146,7 +148,9 @@ class Session extends EventEmitter {
*/
startStreamTo(sessionId, track, stream) {
if (!(sessionId in this.peers)) {
- this._addPeer(sessionId, true);
+ if (!this._addPeer(sessionId, true)) {
+ return;
+ }
}
if (!this.peers[sessionId].ready) {
@@ -192,6 +196,12 @@ class Session extends EventEmitter {
this.socket.emit("join_game", gameId, password);
}
+ /**
+ * Add a new peer connection
+ * @param {string} id
+ * @param {boolean} initiator
+ * @returns {boolean} True if peer was added successfully
+ */
_addPeer(id, initiator) {
try {
const connection = new Connection({
@@ -322,13 +332,15 @@ class Session extends EventEmitter {
peer.connection.on("error", handleError.bind(this));
this.peers[id] = peer;
+
+ return true;
} catch (error) {
logError(error);
this.emit("peerError", { error });
- this.emit("disconnected");
for (let peer of Object.values(this.peers)) {
peer.connection && peer.connection.destroy();
}
+ return false;
}
}
@@ -374,7 +386,9 @@ class Session extends EventEmitter {
_handleSignal(data) {
const { from, signal } = data;
if (!(from in this.peers)) {
- this._addPeer(from, false);
+ if (!this._addPeer(from, false)) {
+ return;
+ }
}
this.peers[from].connection.signal(signal);
}
diff --git a/src/routes/FAQ.js b/src/routes/FAQ.js
index 6d1ebb1..29c90e7 100644
--- a/src/routes/FAQ.js
+++ b/src/routes/FAQ.js
@@ -11,6 +11,7 @@ const database = raw("../docs/faq/database.md");
const maps = raw("../docs/faq/maps.md");
const audioSharing = raw("../docs/faq/audio-sharing.md");
const general = raw("../docs/faq/general.md");
+const connection = raw("../docs/faq/connection.md");
function FAQ() {
return (
@@ -45,6 +46,9 @@ function FAQ() {
+
+
+
diff --git a/src/routes/Game.js b/src/routes/Game.js
index 702180e..5df6f5a 100644
--- a/src/routes/Game.js
+++ b/src/routes/Game.js
@@ -66,9 +66,9 @@ function Game() {
setPeerError("Unable to connect to party.");
}
}
- session.on("error", handlePeerError);
+ session.on("peerError", handlePeerError);
return () => {
- session.off("error", handlePeerError);
+ session.off("peerError", handlePeerError);
};
}, [session]);