Merge branch 'master' into typescript
This commit is contained in:
@@ -58,26 +58,22 @@ class Connection extends SimplePeer {
|
||||
}
|
||||
}
|
||||
|
||||
// Custom send function with encoding, chunking and data channel support
|
||||
// Uses `write` to send the data to allow for buffer / backpressure handling
|
||||
sendObject(object: any, channel: any) {
|
||||
/**
|
||||
* Custom send function with encoding, chunking and data channel support
|
||||
* Uses `write` to send the data to allow for buffer / backpressure handling
|
||||
* @param {any} object
|
||||
* @param {string=} channel
|
||||
* @param {string=} chunkId Optional ID to use for chunking
|
||||
*/
|
||||
sendObject(object: any, channel?: string, chunkId?: string) {
|
||||
try {
|
||||
const packedData = encode(object);
|
||||
if (packedData.byteLength > MAX_BUFFER_SIZE) {
|
||||
const chunks = this.chunk(packedData);
|
||||
for (let chunk of chunks) {
|
||||
if (this.dataChannels[channel]) {
|
||||
this.dataChannels[channel].write(encode(chunk));
|
||||
} else {
|
||||
this.write(encode(chunk));
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
const chunks = this.chunk(packedData, chunkId);
|
||||
for (let chunk of chunks) {
|
||||
if (this.dataChannels[channel]) {
|
||||
this.dataChannels[channel].write(packedData);
|
||||
this.dataChannels[channel].write(encode(chunk));
|
||||
} else {
|
||||
this.write(packedData);
|
||||
this.write(encode(chunk));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -105,11 +101,17 @@ class Connection extends SimplePeer {
|
||||
}
|
||||
|
||||
// Converted from https://github.com/peers/peerjs/
|
||||
chunk(data: any) {
|
||||
/**
|
||||
* Chunk byte array
|
||||
* @param {Uint8Array} data
|
||||
* @param {string=} chunkId
|
||||
* @returns {Uint8Array[]}
|
||||
*/
|
||||
chunk(data: Uint8Array, chunkId?: string) {
|
||||
const chunks = [];
|
||||
const size = data.byteLength;
|
||||
const total = Math.ceil(size / MAX_BUFFER_SIZE);
|
||||
const id = shortid.generate();
|
||||
const id = chunkId || shortid.generate();
|
||||
|
||||
let index = 0;
|
||||
let start = 0;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { useToasts } from "react-toast-notifications";
|
||||
|
||||
import { useTokenData } from "../contexts/TokenDataContext";
|
||||
import { useMapData } from "../contexts/MapDataContext";
|
||||
import { useMapLoading } from "../contexts/MapLoadingContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useUserId } from "../contexts/UserIdContext";
|
||||
import { useDatabase } from "../contexts/DatabaseContext";
|
||||
import { useParty } from "../contexts/PartyContext";
|
||||
import { useAssets } from "../contexts/AssetsContext";
|
||||
|
||||
import { omit } from "../helpers/shared";
|
||||
|
||||
@@ -16,11 +16,16 @@ import useNetworkedState from "../hooks/useNetworkedState";
|
||||
// Load session for auto complete
|
||||
import Session from "./Session";
|
||||
|
||||
import Map, { MapState, Resolutions, TokenState } from "../components/map/Map";
|
||||
import Tokens from "../components/token/Tokens";
|
||||
import { PartyState } from "../components/party/PartyState";
|
||||
import Action from "../actions/Action";
|
||||
import { Token } from "../tokens";
|
||||
|
||||
import Map, {
|
||||
MapState,
|
||||
Map as MapType,
|
||||
TokenState,
|
||||
} from "../components/map/Map";
|
||||
import TokenBar from "../components/token/TokenBar";
|
||||
|
||||
import GlobalImageDrop from "../components/image/GlobalImageDrop";
|
||||
|
||||
const defaultMapActions = {
|
||||
mapDrawActions: [],
|
||||
@@ -39,27 +44,18 @@ const defaultMapActions = {
|
||||
*/
|
||||
function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
const { addToast } = useToasts();
|
||||
const { userId } = useAuth();
|
||||
const partyState: PartyState = useParty();
|
||||
const {
|
||||
assetLoadStart,
|
||||
assetLoadFinish,
|
||||
assetProgressUpdate,
|
||||
isLoading,
|
||||
} = useMapLoading();
|
||||
const userId = useUserId();
|
||||
const partyState = useParty();
|
||||
const { assetLoadStart, assetProgressUpdate, isLoading } = useMapLoading();
|
||||
|
||||
const { putToken, getTokenFromDB } = useTokenData();
|
||||
const { putMap, updateMap, getMapFromDB, updateMapState } = useMapData();
|
||||
const { updateMapState } = useMapData();
|
||||
const { getAsset, putAsset } = useAssets();
|
||||
|
||||
const [currentMap, setCurrentMap] = useState<any>(null);
|
||||
const [currentMapState, setCurrentMapState]: [ currentMapState: MapState, setCurrentMapState: any] = useNetworkedState(
|
||||
null,
|
||||
session,
|
||||
"map_state",
|
||||
500,
|
||||
true,
|
||||
"mapId"
|
||||
);
|
||||
const [currentMapState, setCurrentMapState]: [
|
||||
currentMapState: MapState,
|
||||
setCurrentMapState: any
|
||||
] = useNetworkedState(null, session, "map_state", 500, true, "mapId");
|
||||
const [assetManifest, setAssetManifest] = useNetworkedState(
|
||||
null,
|
||||
session,
|
||||
@@ -69,58 +65,43 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
"mapId"
|
||||
);
|
||||
|
||||
async function loadAssetManifestFromMap(map: any, mapState: MapState) {
|
||||
const assets: any = {};
|
||||
if (map.type === "file") {
|
||||
const { id, lastModified, owner } = map;
|
||||
assets[`map-${id}`] = { type: "map", id, lastModified, owner };
|
||||
}
|
||||
async function loadAssetManifestFromMap(map: MapType, mapState: MapState) {
|
||||
const assets = {};
|
||||
const { owner } = map;
|
||||
let processedTokens = new Set();
|
||||
for (let tokenState of Object.values(mapState.tokens)) {
|
||||
const token = await getTokenFromDB(tokenState.tokenId);
|
||||
if (
|
||||
token &&
|
||||
token.type === "file" &&
|
||||
!processedTokens.has(tokenState.tokenId)
|
||||
) {
|
||||
processedTokens.add(tokenState.tokenId);
|
||||
// Omit file from token peer will request file if needed
|
||||
const { id, lastModified, owner } = token;
|
||||
assets[`token-${id}`] = { type: "token", id, lastModified, owner };
|
||||
if (tokenState.file && !processedTokens.has(tokenState.file)) {
|
||||
processedTokens.add(tokenState.file);
|
||||
assets[tokenState.file] = {
|
||||
id: tokenState.file,
|
||||
owner: tokenState.owner,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (map.type === "file") {
|
||||
assets[map.thumbnail] = { id: map.thumbnail, owner };
|
||||
const qualityId = map.resolutions[map.quality];
|
||||
if (qualityId) {
|
||||
assets[qualityId] = { id: qualityId, owner };
|
||||
} else {
|
||||
assets[map.file] = { id: map.file, owner };
|
||||
}
|
||||
}
|
||||
setAssetManifest({ mapId: map.id, assets }, true, true);
|
||||
}
|
||||
|
||||
function compareAssets(a: any, b: any) {
|
||||
return a.type === b.type && a.id === b.id;
|
||||
}
|
||||
|
||||
// Return true if an asset is out of date
|
||||
function assetNeedsUpdate(oldAsset: any, newAsset: any) {
|
||||
return (
|
||||
compareAssets(oldAsset, newAsset) &&
|
||||
oldAsset.lastModified < newAsset.lastModified
|
||||
);
|
||||
}
|
||||
|
||||
function addAssetIfNeeded(asset: any) {
|
||||
function addAssetsIfNeeded(assets: any[]) {
|
||||
setAssetManifest((prevManifest: any) => {
|
||||
if (prevManifest?.assets) {
|
||||
const id =
|
||||
asset.type === "map" ? `map-${asset.id}` : `token-${asset.id}`;
|
||||
const exists = id in prevManifest.assets;
|
||||
const needsUpdate =
|
||||
exists && assetNeedsUpdate(prevManifest.assets[id], asset);
|
||||
if (!exists || needsUpdate) {
|
||||
return {
|
||||
...prevManifest,
|
||||
assets: {
|
||||
...prevManifest.assets,
|
||||
[id]: asset,
|
||||
},
|
||||
};
|
||||
let newAssets = { ...prevManifest.assets };
|
||||
for (let asset of assets) {
|
||||
const id = asset.id;
|
||||
const exists = id in newAssets;
|
||||
if (!exists) {
|
||||
newAssets[id] = asset;
|
||||
}
|
||||
}
|
||||
return { ...prevManifest, assets: newAssets };
|
||||
}
|
||||
return prevManifest;
|
||||
});
|
||||
@@ -130,7 +111,7 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
const requestingAssetsRef = useRef(new Set());
|
||||
|
||||
useEffect(() => {
|
||||
if (!assetManifest) {
|
||||
if (!assetManifest || !userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -147,33 +128,25 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
(player) => player.userId === asset.owner
|
||||
);
|
||||
|
||||
// Ensure requests are added before any async operation to prevent them from sending twice
|
||||
requestingAssetsRef.current.add(asset.id);
|
||||
|
||||
const cachedAsset = await getAsset(asset.id);
|
||||
if (!owner) {
|
||||
// Add no owner toast if asset is a map and we don't have it in out cache
|
||||
if (asset.type === "map") {
|
||||
const cachedMap = await getMapFromDB(asset.id);
|
||||
if (!cachedMap) {
|
||||
addToast("Unable to find owner for map");
|
||||
}
|
||||
// Add no owner toast if we don't have asset in out cache
|
||||
if (!cachedAsset) {
|
||||
// TODO: Stop toast from appearing multiple times
|
||||
addToast("Unable to find owner for asset");
|
||||
}
|
||||
requestingAssetsRef.current.delete(asset.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
requestingAssetsRef.current.add(asset.id);
|
||||
|
||||
if (asset.type === "map") {
|
||||
const cachedMap = await getMapFromDB(asset.id);
|
||||
if (cachedMap && cachedMap.lastModified === asset.lastModified) {
|
||||
requestingAssetsRef.current.delete(asset.id);
|
||||
} else {
|
||||
session.sendTo(owner.sessionId, "mapRequest", asset.id);
|
||||
}
|
||||
} else if (asset.type === "token") {
|
||||
const cachedToken = await getTokenFromDB(asset.id);
|
||||
if (cachedToken && cachedToken.lastModified === asset.lastModified) {
|
||||
requestingAssetsRef.current.delete(asset.id);
|
||||
} else {
|
||||
session.sendTo(owner.sessionId, "tokenRequest", asset.id);
|
||||
}
|
||||
if (cachedAsset) {
|
||||
requestingAssetsRef.current.delete(asset.id);
|
||||
} else {
|
||||
assetLoadStart(asset.id);
|
||||
session.sendTo(owner.sessionId, "assetRequest", asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,11 +156,10 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
assetManifest,
|
||||
partyState,
|
||||
session,
|
||||
getMapFromDB,
|
||||
getTokenFromDB,
|
||||
updateMap,
|
||||
userId,
|
||||
addToast,
|
||||
getAsset,
|
||||
assetLoadStart,
|
||||
]);
|
||||
|
||||
/**
|
||||
@@ -217,12 +189,8 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
setCurrentMapState(newMapState, true, true);
|
||||
setCurrentMap(newMap);
|
||||
|
||||
if (newMap && newMap.type === "file") {
|
||||
const { file, resolutions, thumbnail, ...rest } = newMap;
|
||||
session.socket?.emit("map", rest);
|
||||
} else {
|
||||
session.socket?.emit("map", newMap);
|
||||
}
|
||||
session.socket?.emit("map", newMap);
|
||||
|
||||
if (!newMap || !newMapState) {
|
||||
setAssetManifest(null, true, true);
|
||||
return;
|
||||
@@ -238,7 +206,12 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
|
||||
const [mapActions, setMapActions] = useState<any>(defaultMapActions);
|
||||
|
||||
function addMapActions(actions: Action[], indexKey: string, actionsKey: any, shapesKey: any) {
|
||||
function addMapActions(
|
||||
actions: Action[],
|
||||
indexKey: string,
|
||||
actionsKey: any,
|
||||
shapesKey: any
|
||||
) {
|
||||
setMapActions((prevMapActions: any) => {
|
||||
const newActions = [
|
||||
...prevMapActions[actionsKey].slice(0, prevMapActions[indexKey] + 1),
|
||||
@@ -266,7 +239,12 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
});
|
||||
}
|
||||
|
||||
function updateActionIndex(change: any, indexKey: any, actionsKey: any, shapesKey: any) {
|
||||
function updateActionIndex(
|
||||
change: any,
|
||||
indexKey: any,
|
||||
actionsKey: any,
|
||||
shapesKey: any
|
||||
) {
|
||||
const prevIndex: any = mapActions[indexKey];
|
||||
const newIndex = Math.min(
|
||||
Math.max(mapActions[indexKey] + change, -1),
|
||||
@@ -369,23 +347,28 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
* Token state
|
||||
*/
|
||||
|
||||
async function handleMapTokenStateCreate(tokenState: TokenState) {
|
||||
async function handleMapTokensStateCreate(tokenStates: TokenState[]) {
|
||||
if (!currentMap || !currentMapState) {
|
||||
return;
|
||||
}
|
||||
// If file type token send the token to the other peers
|
||||
const token: Token = await getTokenFromDB(tokenState.tokenId);
|
||||
if (token && token.type === "file") {
|
||||
const { id, lastModified, owner } = token;
|
||||
addAssetIfNeeded({ type: "token", id, lastModified, owner });
|
||||
|
||||
let assets = [];
|
||||
for (let tokenState of tokenStates) {
|
||||
if (tokenState.type === "file") {
|
||||
assets.push({ id: tokenState.file, owner: tokenState.owner });
|
||||
}
|
||||
}
|
||||
setCurrentMapState((prevMapState: any) => ({
|
||||
...prevMapState,
|
||||
tokens: {
|
||||
...prevMapState.tokens,
|
||||
[tokenState.id]: tokenState,
|
||||
},
|
||||
}));
|
||||
if (assets.length > 0) {
|
||||
addAssetsIfNeeded(assets);
|
||||
}
|
||||
|
||||
setCurrentMapState((prevMapState) => {
|
||||
let newMapTokens = { ...prevMapState.tokens };
|
||||
for (let tokenState of tokenStates) {
|
||||
newMapTokens[tokenState.id] = tokenState;
|
||||
}
|
||||
return { ...prevMapState, tokens: newMapTokens };
|
||||
});
|
||||
}
|
||||
|
||||
function handleMapTokenStateChange(change: any) {
|
||||
@@ -415,114 +398,51 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// TODO: edit Map type with appropriate resolutions
|
||||
async function handlePeerData({ id, data, reply }: { id: string, data: any, reply: any}) {
|
||||
if (id === "mapRequest") {
|
||||
const map = await getMapFromDB(data);
|
||||
function replyWithMap(preview?: string | undefined, resolution?: any) {
|
||||
let response = {
|
||||
...map,
|
||||
thumbnail: undefined,
|
||||
// Remove last modified so if there is an error
|
||||
// during the map request the cache is invalid
|
||||
lastModified: 0,
|
||||
// Add last used for cache invalidation
|
||||
lastUsed: Date.now(),
|
||||
};
|
||||
// Send preview if available
|
||||
if (preview !== undefined && map.resolutions && map.resolutions[preview]) {
|
||||
response.resolutions = { [preview]: map.resolutions[preview] } as Resolutions;
|
||||
reply("mapResponse", response, "map");
|
||||
}
|
||||
// Send full map at the desired resolution if available
|
||||
if (map.resolutions && map.resolutions[resolution]) {
|
||||
response.file = map.resolutions[resolution].file as Uint8Array;
|
||||
} else if (map.file) {
|
||||
// The resolution might not exist for other users so send the file instead
|
||||
response.file = map.file;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
// Add last modified back to file to set cache as valid
|
||||
response.lastModified = map.lastModified;
|
||||
reply("mapResponse", response, "map");
|
||||
}
|
||||
|
||||
switch (map.quality) {
|
||||
case "low":
|
||||
replyWithMap(undefined, "low");
|
||||
break;
|
||||
case "medium":
|
||||
replyWithMap("low", "medium");
|
||||
break;
|
||||
case "high":
|
||||
replyWithMap("medium", "high");
|
||||
break;
|
||||
case "ultra":
|
||||
replyWithMap("medium", "ultra");
|
||||
break;
|
||||
case "original":
|
||||
if (map.resolutions) {
|
||||
if (map.resolutions.medium) {
|
||||
replyWithMap("medium");
|
||||
} else if (map.resolutions.low) {
|
||||
replyWithMap("low");
|
||||
} else {
|
||||
replyWithMap();
|
||||
}
|
||||
} else {
|
||||
replyWithMap();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
replyWithMap();
|
||||
async function handlePeerData({
|
||||
id,
|
||||
data,
|
||||
reply,
|
||||
}: {
|
||||
id: string;
|
||||
data: any;
|
||||
reply: any;
|
||||
}) {
|
||||
if (id === "assetRequest") {
|
||||
const asset = await getAsset(data.id);
|
||||
if (asset) {
|
||||
reply("assetResponseSuccess", asset, undefined, data.id);
|
||||
} else {
|
||||
reply("assetResponseFail", data.id, undefined, data.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (id === "mapResponse") {
|
||||
const newMap = data;
|
||||
if (newMap?.id) {
|
||||
setCurrentMap(newMap);
|
||||
await putMap(newMap);
|
||||
// If we have the final map resolution
|
||||
if (newMap.lastModified > 0) {
|
||||
requestingAssetsRef.current.delete(newMap.id);
|
||||
}
|
||||
}
|
||||
assetLoadFinish();
|
||||
if (id === "assetResponseSuccess") {
|
||||
const asset = data;
|
||||
await putAsset(asset);
|
||||
requestingAssetsRef.current.delete(asset.id);
|
||||
}
|
||||
|
||||
if (id === "tokenRequest") {
|
||||
const token = await getTokenFromDB(data);
|
||||
// Add a last used property for cache invalidation
|
||||
reply("tokenResponse", { ...token, lastUsed: Date.now() }, "token");
|
||||
}
|
||||
if (id === "tokenResponse") {
|
||||
const newToken = data;
|
||||
if (newToken?.id) {
|
||||
await putToken(newToken);
|
||||
requestingAssetsRef.current.delete(newToken.id);
|
||||
}
|
||||
assetLoadFinish();
|
||||
if (id === "assetResponseFail") {
|
||||
const assetId = data;
|
||||
requestingAssetsRef.current.delete(assetId);
|
||||
}
|
||||
}
|
||||
|
||||
function handlePeerDataProgress({ id, total, count }: { id: string, total: number, count: number}) {
|
||||
if (count === 1) {
|
||||
// Corresponding asset load finished called in token and map response
|
||||
assetLoadStart();
|
||||
}
|
||||
function handlePeerDataProgress({
|
||||
id,
|
||||
total,
|
||||
count,
|
||||
}: {
|
||||
id: string;
|
||||
total: number;
|
||||
count: number;
|
||||
}) {
|
||||
assetProgressUpdate({ id, total, count });
|
||||
}
|
||||
|
||||
async function handleSocketMap(map: any) {
|
||||
if (map) {
|
||||
if (map.type === "file") {
|
||||
const fullMap = await getMapFromDB(map.id);
|
||||
setCurrentMap(fullMap || map);
|
||||
} else {
|
||||
setCurrentMap(map);
|
||||
}
|
||||
setCurrentMap(map);
|
||||
} else {
|
||||
setCurrentMap(null);
|
||||
}
|
||||
@@ -575,7 +495,10 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<GlobalImageDrop
|
||||
onMapChange={handleMapChange}
|
||||
onMapTokensStateCreate={handleMapTokensStateCreate}
|
||||
>
|
||||
<Map
|
||||
map={currentMap}
|
||||
mapState={currentMapState}
|
||||
@@ -599,8 +522,8 @@ function NetworkedMapAndTokens({ session }: { session: Session }) {
|
||||
disabledTokens={disabledMapTokens}
|
||||
session={session}
|
||||
/>
|
||||
<Tokens onMapTokenStateCreate={handleMapTokenStateCreate} />
|
||||
</>
|
||||
<TokenBar onMapTokensStateCreate={handleMapTokensStateCreate} />
|
||||
</GlobalImageDrop>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Group } from "react-konva";
|
||||
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useUserId } from "../contexts/UserIdContext";
|
||||
|
||||
import MapPointer from "../components/map/MapPointer";
|
||||
import { isEmpty } from "../helpers/shared";
|
||||
@@ -13,8 +13,14 @@ import Session from "./Session";
|
||||
// Send pointer updates every 50ms (20fps)
|
||||
const sendTickRate = 50;
|
||||
|
||||
function NetworkedMapPointer({ session, active }: { session: Session, active: boolean }) {
|
||||
const { userId } = useAuth();
|
||||
function NetworkedMapPointer({
|
||||
session,
|
||||
active,
|
||||
}: {
|
||||
session: Session;
|
||||
active: boolean;
|
||||
}) {
|
||||
const userId = useUserId();
|
||||
const [localPointerState, setLocalPointerState] = useState({});
|
||||
const [pointerColor] = useSetting("pointer.color");
|
||||
|
||||
@@ -39,7 +45,9 @@ function NetworkedMapPointer({ session, active }: { session: Session, active: bo
|
||||
// Send pointer updates every sendTickRate to peers to save on bandwidth
|
||||
// We use requestAnimationFrame as setInterval was being blocked during
|
||||
// re-renders on Chrome with Windows
|
||||
const ownPointerUpdateRef: React.MutableRefObject<{ position: any; visible: boolean; id: any; color: any; } | undefined | null > = useRef();
|
||||
const ownPointerUpdateRef: React.MutableRefObject<
|
||||
{ position: any; visible: boolean; id: any; color: any } | undefined | null
|
||||
> = useRef();
|
||||
useEffect(() => {
|
||||
let prevTime = performance.now();
|
||||
let request = requestAnimationFrame(update);
|
||||
|
||||
@@ -26,7 +26,8 @@ export type SessionPeer = {
|
||||
* @callback peerReply
|
||||
* @param {string} id - The id of the event
|
||||
* @param {object} data - The data to send
|
||||
* @param {string} channel - The channel to send to
|
||||
* @param {string=} channel - The channel to send to
|
||||
* @param {string=} chunkId
|
||||
*/
|
||||
|
||||
type peerReply = (id: string, data: SimplePeerData, channel: string) => void;
|
||||
@@ -126,7 +127,7 @@ class Session extends EventEmitter {
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.socket.disconnect();
|
||||
this.socket?.disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,9 +136,10 @@ class Session extends EventEmitter {
|
||||
* @param {string} sessionId - The socket id of the player to send to
|
||||
* @param {string} eventId - The id of the event to send
|
||||
* @param {object} data
|
||||
* @param {string} channel
|
||||
* @param {string=} channel
|
||||
* @param {string=} chunkId
|
||||
*/
|
||||
sendTo(sessionId: string, eventId: string, data: SimplePeerData, channel?: string) {
|
||||
sendTo(sessionId: string, eventId: string, data: any, channel?: string, chunkId?: string) {
|
||||
if (!(sessionId in this.peers)) {
|
||||
if (!this._addPeer(sessionId, true)) {
|
||||
return;
|
||||
@@ -148,7 +150,8 @@ class Session extends EventEmitter {
|
||||
this.peers[sessionId].connection.once("connect", () => {
|
||||
this.peers[sessionId].connection.sendObject(
|
||||
{ id: eventId, data },
|
||||
channel
|
||||
channel,
|
||||
chunkId
|
||||
);
|
||||
});
|
||||
} else {
|
||||
@@ -245,9 +248,9 @@ class Session extends EventEmitter {
|
||||
|
||||
const peer = { id, connection, initiator, ready: false };
|
||||
|
||||
const sendPeer = (id: string, data: SimplePeerData, channel: any) => {
|
||||
peer.connection.sendObject({ id, data }, channel);
|
||||
};
|
||||
function reply(id: string, data: any, channel?: string, chunkId?: string) {
|
||||
peer.connection.sendObject({ id, data }, channel, chunkId);
|
||||
}
|
||||
|
||||
const handleSignal = (signal: any) => {
|
||||
this.socket.emit("signal", JSON.stringify({ to: peer.id, signal }));
|
||||
@@ -265,12 +268,8 @@ class Session extends EventEmitter {
|
||||
* @property {SessionPeer} peer
|
||||
* @property {peerReply} reply
|
||||
*/
|
||||
const peerConnectEvent: { peer: SessionPeer; reply: peerReply } = {
|
||||
peer,
|
||||
reply: sendPeer,
|
||||
};
|
||||
this.emit("peerConnect", peerConnectEvent);
|
||||
};
|
||||
this.emit("peerConnect", { peer, reply });
|
||||
}
|
||||
|
||||
const handleDataComplete = (data: any) => {
|
||||
/**
|
||||
@@ -292,7 +291,7 @@ class Session extends EventEmitter {
|
||||
peer,
|
||||
id: data.id,
|
||||
data: data.data,
|
||||
reply: sendPeer,
|
||||
reply: reply,
|
||||
};
|
||||
console.log(`Data: ${JSON.stringify(data)}`)
|
||||
this.emit("peerData", peerDataEvent);
|
||||
@@ -312,7 +311,7 @@ class Session extends EventEmitter {
|
||||
id,
|
||||
count,
|
||||
total,
|
||||
reply: sendPeer,
|
||||
reply,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user