Merge pull request #11 from mitchemmc/feature/disconnect-detection

v1.3.3
This commit is contained in:
Mitchell McCaffrey 2020-06-16 22:14:37 +10:00 committed by GitHub
commit 97dfc9f673
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 35 deletions

View File

@ -1,6 +1,6 @@
{
"name": "owlbear-rodeo",
"version": "1.3.2",
"version": "1.3.3",
"private": true,
"dependencies": {
"@msgpack/msgpack": "^1.12.1",

View File

@ -2,7 +2,7 @@ import React from "react";
import Modal from "react-modal";
import { useThemeUI, Close } from "theme-ui";
function Banner({ isOpen, onRequestClose, children }) {
function Banner({ isOpen, onRequestClose, children, allowClose }) {
const { theme } = useThemeUI();
return (
@ -15,7 +15,7 @@ function Banner({ isOpen, onRequestClose, children }) {
backgroundColor: theme.colors.highlight,
top: "initial",
left: "50%",
right: 0,
right: "initial",
// Offset for iOS safe zone
bottom: "env(safe-area-inset-bottom)",
border: "none",
@ -28,13 +28,19 @@ function Banner({ isOpen, onRequestClose, children }) {
}}
>
{children}
<Close
m={0}
sx={{ position: "absolute", top: "4px", right: 0 }}
onClick={onRequestClose}
/>
{allowClose && (
<Close
m={0}
sx={{ position: "absolute", top: "4px", right: 0 }}
onClick={onRequestClose}
/>
)}
</Modal>
);
}
Banner.defaultProps = {
allowClose: true,
};
export default Banner;

View File

@ -0,0 +1,8 @@
# v1.3.3
## Minor Changes
- Fixed a bug that would cause the game to crash when a player would lose internet connection.
- Added an automatic reconnection feature for when internet connection is lost. This should also help when players put the site into the background and try and return to the game later.
[Reddit]()

View File

@ -1,4 +1,4 @@
import { useEffect, useState, useContext } from "react";
import { useEffect, useState, useContext, useCallback } from "react";
import io from "socket.io-client";
import { omit } from "../helpers/shared";
@ -19,17 +19,24 @@ function useSession(
) {
const { password, setAuthenticationStatus } = useContext(AuthContext);
const [iceServers, setIceServers] = useState([]);
const [connected, setConnected] = useState(false);
useEffect(() => {
async function joinParty() {
const joinParty = useCallback(async () => {
try {
const response = await fetch(process.env.REACT_APP_ICE_SERVERS_URL);
const data = await response.json();
setIceServers(data.iceServers);
socket.emit("join party", partyId, password);
} catch (e) {
console.error("Unable to join party:", e.message);
setConnected(false);
}
joinParty();
}, [partyId, password]);
useEffect(() => {
joinParty();
}, [partyId, password, joinParty]);
const [peers, setPeers] = useState({});
// Signal connected peers of a closure on refresh
@ -78,6 +85,8 @@ function useSession(
function handleClose() {
onPeerDisconnected && onPeerDisconnected(peer);
peer.connection.destroy();
setPeers((prevPeers) => omit(prevPeers, [peer.id]));
}
function handleError(error) {
@ -153,8 +162,8 @@ function useSession(
function handlePartyMemberLeft(id) {
if (id in peers) {
peers[id].connection.destroy();
setPeers((prevPeers) => omit(prevPeers, [id]));
}
setPeers((prevPeers) => omit(prevPeers, [id]));
}
function handleJoinedParty(otherIds) {
@ -164,6 +173,7 @@ function useSession(
addPeer(id, true, sync);
}
setAuthenticationStatus("authenticated");
setConnected(true);
}
function handleSignal(data) {
@ -177,21 +187,36 @@ function useSession(
setAuthenticationStatus("unauthenticated");
}
function handleSocketDisconnect() {
setConnected(false);
}
function handleSocketReconnect() {
setConnected(true);
joinParty();
}
socket.on("disconnect", handleSocketDisconnect);
socket.on("reconnect", handleSocketReconnect);
socket.on("party member joined", handlePartyMemberJoined);
socket.on("party member left", handlePartyMemberLeft);
socket.on("joined party", handleJoinedParty);
socket.on("signal", handleSignal);
socket.on("auth error", handleAuthError);
return () => {
socket.removeListener("party member joined", handlePartyMemberJoined);
socket.removeListener("party member left", handlePartyMemberLeft);
socket.removeListener("joined party", handleJoinedParty);
socket.removeListener("signal", handleSignal);
socket.removeListener("auth error", handleAuthError);
};
}, [peers, setAuthenticationStatus, iceServers]);
socket.off("disconnect", handleSocketDisconnect);
socket.off("reconnect", handleSocketReconnect);
return { peers, socket };
socket.off("party member joined", handlePartyMemberJoined);
socket.off("party member left", handlePartyMemberLeft);
socket.off("joined party", handleJoinedParty);
socket.off("signal", handleSignal);
socket.off("auth error", handleAuthError);
};
}, [peers, setAuthenticationStatus, iceServers, joinParty]);
return { peers, socket, connected };
}
export default useSession;

View File

@ -35,7 +35,7 @@ function Game() {
);
const { assetLoadStart, assetLoadFinish } = useContext(MapLoadingContext);
const { peers, socket } = useSession(
const { peers, socket, connected } = useSession(
gameId,
handlePeerConnected,
handlePeerDisconnected,
@ -421,18 +421,6 @@ function Game() {
const [peerError, setPeerError] = useState(null);
function handlePeerError({ error, peer }) {
console.error(error.code);
if (
error.code === "ERR_ICE_CONNECTION_FAILURE" ||
error.code === "ERR_CONNECTION_FAILURE"
) {
setPeerError(
`${
peer.id === socket.id
? ""
: `(${partyNicknames[peer.id] || "Unknown"})`
} Connection failure`
);
}
if (error.code === "ERR_WEBRTC_SUPPORT") {
setPeerError("WebRTC not supported");
}
@ -558,6 +546,17 @@ function Game() {
</Text>
</Box>
</Banner>
<Banner
isOpen={!connected && authenticationStatus === "authenticated"}
onRequestClose={() => {}}
allowClose={false}
>
<Box p={1}>
<Text as="p" variant="body2">
Disconnected. Attempting to reconnect...
</Text>
</Box>
</Banner>
<AuthModal isOpen={authenticationStatus === "unauthenticated"} />
{authenticationStatus === "unknown" && <LoadingOverlay />}
</MapStageProvider>

View File

@ -51,7 +51,7 @@ function Home() {
Join Game
</Button>
<Text variant="caption" as="p" sx={{ textAlign: "center" }}>
Beta v1.3.2
Beta v1.3.3
</Text>
<Button
m={2}

View File

@ -11,6 +11,7 @@ const v121 = raw("../docs/releaseNotes/v1.2.1.md");
const v130 = raw("../docs/releaseNotes/v1.3.0.md");
const v131 = raw("../docs/releaseNotes/v1.3.1.md");
const v132 = raw("../docs/releaseNotes/v1.3.2.md");
const v133 = raw("../docs/releaseNotes/v1.3.3.md");
function ReleaseNotes() {
return (
@ -33,6 +34,9 @@ function ReleaseNotes() {
<Text mb={2} variant="heading" as="h1" sx={{ fontSize: 5 }}>
Release Notes
</Text>
<div id="v133">
<Markdown source={v133} />
</div>
<div id="v132">
<Markdown source={v132} />
</div>