Spaces:
Sleeping
Sleeping
multiplayer
Browse files
patches/convex/world.ts
CHANGED
|
@@ -98,30 +98,37 @@ export const restartDeadWorlds = internalMutation({
|
|
| 98 |
export const userStatus = query({
|
| 99 |
args: {
|
| 100 |
worldId: v.id('worlds'),
|
|
|
|
|
|
|
| 101 |
},
|
| 102 |
handler: async (ctx, args) => {
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
|
|
|
| 109 |
},
|
| 110 |
});
|
| 111 |
|
| 112 |
export const joinWorld = mutation({
|
| 113 |
args: {
|
| 114 |
-
|
|
|
|
| 115 |
},
|
| 116 |
handler: async (ctx, args) => {
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
// if (!identity) {
|
| 119 |
// throw new ConvexError(`Not logged in`);
|
| 120 |
// }
|
| 121 |
// const name =
|
| 122 |
// identity.givenName || identity.nickname || (identity.email && identity.email.split('@')[0]);
|
| 123 |
-
|
| 124 |
-
|
| 125 |
// if (!name) {
|
| 126 |
// throw new ConvexError(`Missing name on ${JSON.stringify(identity)}`);
|
| 127 |
// }
|
|
@@ -154,7 +161,7 @@ export const joinWorld = mutation({
|
|
| 154 |
character: randomCharacter.character,
|
| 155 |
description: randomCharacter.identity,
|
| 156 |
// description: `${identity.givenName} is a human player`,
|
| 157 |
-
tokenIdentifier:
|
| 158 |
// By default everybody is a villager
|
| 159 |
type: 'villager',
|
| 160 |
});
|
|
@@ -164,19 +171,21 @@ export const joinWorld = mutation({
|
|
| 164 |
export const leaveWorld = mutation({
|
| 165 |
args: {
|
| 166 |
worldId: v.id('worlds'),
|
|
|
|
| 167 |
},
|
| 168 |
handler: async (ctx, args) => {
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
|
|
|
| 174 |
const world = await ctx.db.get(args.worldId);
|
| 175 |
if (!world) {
|
| 176 |
throw new Error(`Invalid world ID: ${args.worldId}`);
|
| 177 |
}
|
| 178 |
// const existingPlayer = world.players.find((p) => p.human === tokenIdentifier);
|
| 179 |
-
const existingPlayer = world.players.find((p) => p.human ===
|
| 180 |
if (!existingPlayer) {
|
| 181 |
return;
|
| 182 |
}
|
|
|
|
| 98 |
export const userStatus = query({
|
| 99 |
args: {
|
| 100 |
worldId: v.id('worlds'),
|
| 101 |
+
oauthToken: v.optional(v.string()),
|
| 102 |
+
|
| 103 |
},
|
| 104 |
handler: async (ctx, args) => {
|
| 105 |
+
const { worldId, oauthToken } = args;
|
| 106 |
+
|
| 107 |
+
if (!oauthToken) {
|
| 108 |
+
return null;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
return oauthToken;
|
| 112 |
},
|
| 113 |
});
|
| 114 |
|
| 115 |
export const joinWorld = mutation({
|
| 116 |
args: {
|
| 117 |
+
oauthToken: v.optional(v.string()),
|
| 118 |
+
|
| 119 |
},
|
| 120 |
handler: async (ctx, args) => {
|
| 121 |
+
const { worldId, oauthToken } = args;
|
| 122 |
+
|
| 123 |
+
if (!oauthToken) {
|
| 124 |
+
throw new ConvexError(`Not logged in`);
|
| 125 |
+
}
|
| 126 |
// if (!identity) {
|
| 127 |
// throw new ConvexError(`Not logged in`);
|
| 128 |
// }
|
| 129 |
// const name =
|
| 130 |
// identity.givenName || identity.nickname || (identity.email && identity.email.split('@')[0]);
|
| 131 |
+
const name = oauthToken;
|
|
|
|
| 132 |
// if (!name) {
|
| 133 |
// throw new ConvexError(`Missing name on ${JSON.stringify(identity)}`);
|
| 134 |
// }
|
|
|
|
| 161 |
character: randomCharacter.character,
|
| 162 |
description: randomCharacter.identity,
|
| 163 |
// description: `${identity.givenName} is a human player`,
|
| 164 |
+
tokenIdentifier: oauthToken, // TODO: change for multiplayer to oauth
|
| 165 |
// By default everybody is a villager
|
| 166 |
type: 'villager',
|
| 167 |
});
|
|
|
|
| 171 |
export const leaveWorld = mutation({
|
| 172 |
args: {
|
| 173 |
worldId: v.id('worlds'),
|
| 174 |
+
oauthToken: v.optional(v.string()),
|
| 175 |
},
|
| 176 |
handler: async (ctx, args) => {
|
| 177 |
+
const { worldId, oauthToken } = args;
|
| 178 |
+
|
| 179 |
+
if (!oauthToken) {
|
| 180 |
+
throw new ConvexError(`Not logged in`);
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
const world = await ctx.db.get(args.worldId);
|
| 184 |
if (!world) {
|
| 185 |
throw new Error(`Invalid world ID: ${args.worldId}`);
|
| 186 |
}
|
| 187 |
// const existingPlayer = world.players.find((p) => p.human === tokenIdentifier);
|
| 188 |
+
const existingPlayer = world.players.find((p) => p.human === oauthToken);
|
| 189 |
if (!existingPlayer) {
|
| 190 |
return;
|
| 191 |
}
|
patches/src/App.tsx
CHANGED
|
@@ -13,6 +13,7 @@ import ReactModal from 'react-modal';
|
|
| 13 |
import MusicButton from './components/buttons/MusicButton.tsx';
|
| 14 |
import Button from './components/buttons/Button.tsx';
|
| 15 |
import InteractButton from './components/buttons/InteractButton.tsx';
|
|
|
|
| 16 |
import FreezeButton from './components/FreezeButton.tsx';
|
| 17 |
import { MAX_HUMAN_PLAYERS } from '../convex/constants.ts';
|
| 18 |
import PoweredByConvex from './components/PoweredByConvex.tsx';
|
|
@@ -82,6 +83,7 @@ export default function Home() {
|
|
| 82 |
<Button imgUrl={helpImg} onClick={() => setHelpModalOpen(true)}>
|
| 83 |
Help
|
| 84 |
</Button>
|
|
|
|
| 85 |
<div id="footer-buttons"/>
|
| 86 |
</div>
|
| 87 |
</footer>
|
|
|
|
| 13 |
import MusicButton from './components/buttons/MusicButton.tsx';
|
| 14 |
import Button from './components/buttons/Button.tsx';
|
| 15 |
import InteractButton from './components/buttons/InteractButton.tsx';
|
| 16 |
+
import OAuthLogin from './components//buttons/OAuthLogin.tsx';
|
| 17 |
import FreezeButton from './components/FreezeButton.tsx';
|
| 18 |
import { MAX_HUMAN_PLAYERS } from '../convex/constants.ts';
|
| 19 |
import PoweredByConvex from './components/PoweredByConvex.tsx';
|
|
|
|
| 83 |
<Button imgUrl={helpImg} onClick={() => setHelpModalOpen(true)}>
|
| 84 |
Help
|
| 85 |
</Button>
|
| 86 |
+
<OAuthLogin />
|
| 87 |
<div id="footer-buttons"/>
|
| 88 |
</div>
|
| 89 |
</footer>
|
patches/src/components/PixiGame.tsx
CHANGED
|
@@ -27,8 +27,9 @@ export const PixiGame = (props: {
|
|
| 27 |
// PIXI setup.
|
| 28 |
const pixiApp = useApp();
|
| 29 |
const viewportRef = useRef<Viewport | undefined>();
|
| 30 |
-
|
| 31 |
-
const
|
|
|
|
| 32 |
const humanPlayerId = [...props.game.world.players.values()].find(
|
| 33 |
(p) => p.human === humanTokenIdentifier,
|
| 34 |
)?.id;
|
|
|
|
| 27 |
// PIXI setup.
|
| 28 |
const pixiApp = useApp();
|
| 29 |
const viewportRef = useRef<Viewport | undefined>();
|
| 30 |
+
const oauth = JSON.parse(localStorage.getItem('oauth'));
|
| 31 |
+
const oauthToken = oauth ? oauth.userInfo.fullname : undefined;
|
| 32 |
+
const humanTokenIdentifier = useQuery(api.world.userStatus, { worldId: props.worldId, oauthToken }) ?? null;
|
| 33 |
const humanPlayerId = [...props.game.world.players.values()].find(
|
| 34 |
(p) => p.human === humanTokenIdentifier,
|
| 35 |
)?.id;
|
patches/src/components/PlayerDetails.tsx
CHANGED
|
@@ -25,7 +25,9 @@ export default function PlayerDetails({
|
|
| 25 |
setSelectedElement: SelectElement;
|
| 26 |
scrollViewRef: React.RefObject<HTMLDivElement>;
|
| 27 |
}) {
|
| 28 |
-
const
|
|
|
|
|
|
|
| 29 |
|
| 30 |
const players = [...game.world.players.values()];
|
| 31 |
const humanPlayer = players.find((p) => p.human === humanTokenIdentifier);
|
|
|
|
| 25 |
setSelectedElement: SelectElement;
|
| 26 |
scrollViewRef: React.RefObject<HTMLDivElement>;
|
| 27 |
}) {
|
| 28 |
+
const oauth = JSON.parse(localStorage.getItem('oauth'));
|
| 29 |
+
const oauthToken = oauth ? oauth.userInfo.fullname : undefined;
|
| 30 |
+
const humanTokenIdentifier = useQuery(api.world.userStatus, { worldId, oauthToken });
|
| 31 |
|
| 32 |
const players = [...game.world.players.values()];
|
| 33 |
const humanPlayer = players.find((p) => p.human === humanTokenIdentifier);
|
patches/src/components/buttons/InteractButton.tsx
CHANGED
|
@@ -15,7 +15,9 @@ export default function InteractButton() {
|
|
| 15 |
const worldStatus = useQuery(api.world.defaultWorldStatus);
|
| 16 |
const worldId = worldStatus?.worldId;
|
| 17 |
const game = useServerGame(worldId);
|
| 18 |
-
const
|
|
|
|
|
|
|
| 19 |
const userPlayerId =
|
| 20 |
game && [...game.world.players.values()].find((p) => p.human === humanTokenIdentifier)?.id;
|
| 21 |
const join = useMutation(api.world.joinWorld);
|
|
@@ -27,7 +29,7 @@ export default function InteractButton() {
|
|
| 27 |
async (worldId: Id<'worlds'>) => {
|
| 28 |
let inputId;
|
| 29 |
try {
|
| 30 |
-
inputId = await join({ worldId });
|
| 31 |
} catch (e: any) {
|
| 32 |
if (e instanceof ConvexError) {
|
| 33 |
toast.error(e.data);
|
|
@@ -41,7 +43,7 @@ export default function InteractButton() {
|
|
| 41 |
toast.error(e.message);
|
| 42 |
}
|
| 43 |
},
|
| 44 |
-
[convex],
|
| 45 |
);
|
| 46 |
|
| 47 |
const joinOrLeaveGame = () => {
|
|
@@ -54,7 +56,7 @@ export default function InteractButton() {
|
|
| 54 |
}
|
| 55 |
if (isPlaying) {
|
| 56 |
console.log(`Leaving game for player ${userPlayerId}`);
|
| 57 |
-
void leave({ worldId });
|
| 58 |
} else {
|
| 59 |
console.log(`Joining game`);
|
| 60 |
void joinInput(worldId);
|
|
|
|
| 15 |
const worldStatus = useQuery(api.world.defaultWorldStatus);
|
| 16 |
const worldId = worldStatus?.worldId;
|
| 17 |
const game = useServerGame(worldId);
|
| 18 |
+
const oauth = JSON.parse(localStorage.getItem('oauth'));
|
| 19 |
+
const oauthToken = oauth ? oauth.userInfo.fullname : undefined;
|
| 20 |
+
const humanTokenIdentifier = useQuery(api.world.userStatus, worldId ? { worldId, oauthToken } : 'skip');
|
| 21 |
const userPlayerId =
|
| 22 |
game && [...game.world.players.values()].find((p) => p.human === humanTokenIdentifier)?.id;
|
| 23 |
const join = useMutation(api.world.joinWorld);
|
|
|
|
| 29 |
async (worldId: Id<'worlds'>) => {
|
| 30 |
let inputId;
|
| 31 |
try {
|
| 32 |
+
inputId = await join({ worldId, oauthToken });
|
| 33 |
} catch (e: any) {
|
| 34 |
if (e instanceof ConvexError) {
|
| 35 |
toast.error(e.data);
|
|
|
|
| 43 |
toast.error(e.message);
|
| 44 |
}
|
| 45 |
},
|
| 46 |
+
[convex, join, oauthToken],
|
| 47 |
);
|
| 48 |
|
| 49 |
const joinOrLeaveGame = () => {
|
|
|
|
| 56 |
}
|
| 57 |
if (isPlaying) {
|
| 58 |
console.log(`Leaving game for player ${userPlayerId}`);
|
| 59 |
+
void leave({ worldId , oauthToken});
|
| 60 |
} else {
|
| 61 |
console.log(`Joining game`);
|
| 62 |
void joinInput(worldId);
|