From aef82affc5c48afc4d72d705f991d3c39e6a3498 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Thu, 13 Jun 2024 20:29:34 +0200
Subject: [PATCH] zone editor stuff

---
 src/app/ZoneManager.ts                        |  8 ++--
 src/app/events/CharacterZoneLeave.ts          | 48 +++++++++++++++++++
 ...terZoneLoad.ts => CharacterZoneRequest.ts} |  6 +--
 src/app/events/Disconnect.ts                  |  9 +++-
 src/app/events/GmZoneEditorZoneRequest.ts     | 39 +++++++++++++++
 5 files changed, 99 insertions(+), 11 deletions(-)
 create mode 100644 src/app/events/CharacterZoneLeave.ts
 rename src/app/events/{CharacterZoneLoad.ts => CharacterZoneRequest.ts} (86%)
 create mode 100644 src/app/events/GmZoneEditorZoneRequest.ts

diff --git a/src/app/ZoneManager.ts b/src/app/ZoneManager.ts
index 81a8df1..6ad358f 100644
--- a/src/app/ZoneManager.ts
+++ b/src/app/ZoneManager.ts
@@ -57,15 +57,13 @@ class ZoneManager {
         }
     }
 
-    public removeCharacterFromZone(zoneId: number, characterId: number) {
+    public removeCharacterFromZone(zoneId: number, character: Character) {
         const loadedZone = this.loadedZones.find((loadedZone) => {
-            console.log('Checking zone', loadedZone.zone.id, zoneId);
             return loadedZone.zone.id === zoneId;
         });
         if (loadedZone) {
-            console.log('Removing character from zone', characterId);
-            loadedZone.characters = loadedZone.characters.filter((character) => {
-                return character.id !== characterId;
+            loadedZone.characters = loadedZone.characters.filter((loadedCharacter) => {
+                return loadedCharacter.id !== character.id;
             });
         }
     }
diff --git a/src/app/events/CharacterZoneLeave.ts b/src/app/events/CharacterZoneLeave.ts
new file mode 100644
index 0000000..c41cdfe
--- /dev/null
+++ b/src/app/events/CharacterZoneLeave.ts
@@ -0,0 +1,48 @@
+import { Server } from "socket.io";
+import {TSocket} from "../utilities/Types";
+import ZoneRepository from "../repositories/ZoneRepository";
+import ZoneManager from "../ZoneManager";
+import {Character, Zone} from "@prisma/client";
+
+/**
+ * Handle character zone leave event
+ * @param socket
+ * @param io
+ */
+export default function (socket: TSocket, io: Server) {
+    socket.on('character:zone:leave', async () => {
+        console.log(`---Socket ${socket.character?.id} has leaved zone.`);
+
+        if (!socket.character) {
+            console.log('Socket leaved zone but had no character set');
+            return;
+        }
+
+        if (!socket.character.zoneId) {
+            console.log(`---Zone id not provided.`);
+            return;
+        }
+
+        const zone = await ZoneRepository.getById(socket.character.zoneId);
+
+        if (!zone) {
+            console.log(`---Zone not found.`);
+            return;
+        }
+
+        socket.leave(zone.id.toString());
+
+        socket.emit('character:zone:unload');
+
+        // let other clients know of new character
+        io.to(zone.id.toString()).emit('zone:character:leave', socket.character);
+
+        // add character to zone manager
+        ZoneManager.removeCharacterFromZone(zone.id, socket.character as Character);
+    });
+}
+
+/**
+ * Resources:
+ * https://stackoverflow.com/questions/6873607/socket-io-rooms-difference-between-broadcast-to-and-sockets-in
+ */
\ No newline at end of file
diff --git a/src/app/events/CharacterZoneLoad.ts b/src/app/events/CharacterZoneRequest.ts
similarity index 86%
rename from src/app/events/CharacterZoneLoad.ts
rename to src/app/events/CharacterZoneRequest.ts
index 40f0737..febd33a 100644
--- a/src/app/events/CharacterZoneLoad.ts
+++ b/src/app/events/CharacterZoneRequest.ts
@@ -9,14 +9,12 @@ interface IZoneLoad {
 }
 
 /**
- * @TODO: Implement zone loading, check if zone id is given or else load current character zone
- *
- * Handle character zone load event
+ * Handle character zone request event
  * @param socket
  * @param io
  */
 export default function (socket: TSocket, io: Server) {
-    socket.on('character:zone:load', async (data: IZoneLoad) => {
+    socket.on('character:zone:request', async (data: IZoneLoad) => {
         console.log(`---User ${socket.character?.id} has requested zone.`);
 
         if (!data.zoneId) {
diff --git a/src/app/events/Disconnect.ts b/src/app/events/Disconnect.ts
index 1850d90..bd8ae13 100644
--- a/src/app/events/Disconnect.ts
+++ b/src/app/events/Disconnect.ts
@@ -4,15 +4,20 @@ import ZoneManager from "../ZoneManager";
 
 export default function (socket: TSocket, io: Server) {
     socket.on('disconnect', (data: any) => {
+        if (!socket.user) {
+            console.log('User disconnected but had no user set');
+            return;
+        }
 
+        io.emit('user:disconnect', socket.user.id);
 
         if (!socket.character) {
             console.log('User disconnected but had no character set');
             return;
         }
 
-        ZoneManager.removeCharacterFromZone(socket.character.zoneId, socket.character.id);
+        ZoneManager.removeCharacterFromZone(socket.character.zoneId, socket.character);
 
-        io.emit('user:disconnect', socket.character);
+        io.emit('character:disconnect', socket.character.id);
     });
 }
\ No newline at end of file
diff --git a/src/app/events/GmZoneEditorZoneRequest.ts b/src/app/events/GmZoneEditorZoneRequest.ts
new file mode 100644
index 0000000..afff97a
--- /dev/null
+++ b/src/app/events/GmZoneEditorZoneRequest.ts
@@ -0,0 +1,39 @@
+import { Server } from "socket.io";
+import {TSocket} from "../utilities/Types";
+import ZoneRepository from "../repositories/ZoneRepository";
+import ZoneManager from "../ZoneManager";
+import {Character, Zone} from "@prisma/client";
+
+interface IZoneLoad {
+    zoneId: number;
+}
+
+/**
+ * Handle character zone request event
+ * @param socket
+ * @param io
+ */
+export default function (socket: TSocket, io: Server) {
+    socket.on('gm:zone_editor:zone:request', async (data: IZoneLoad) => {
+        console.log(`---GM ${socket.character?.id} has requested zone in zone editor.`);
+
+        if (!data.zoneId) {
+            console.log(`---Zone id not provided.`);
+            return;
+        }
+
+        const zone = await ZoneRepository.getById(data.zoneId);
+
+        if (!zone) {
+            console.log(`---Zone not found.`);
+            return;
+        }
+
+        socket.join(zone.id.toString());
+
+        // send over zone and characters to socket
+        socket.emit('gm:zone_editor:zone:load', {
+            zone: zone
+        });
+    });
+}
\ No newline at end of file