GameSession *gameSessionNew(Commander *commander) { GameSession *self; if ((self = calloc(1, sizeof(GameSession))) == NULL) { return NULL; } if (!gameSessionInit (self, commander)) { gameSessionDestroy (&self); error("GameSession failed to initialize."); return NULL; } return self; }
bool sessionInit(Session *self, RouterId_t routerId, uint8_t *sessionKey) { // Define a valid socket session socketSessionInit(&self->socket, SOCKET_SESSION_UNDEFINED_ACCOUNT, routerId, SOCKET_SESSION_UNDEFINED_MAP, sessionKey, false); // Initialize a dummy commander info Commander commander; commanderInit(&commander); gameSessionInit(&self->game, &commander); return true; }
void adminCmdSpawnPc(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { // add a fake commander with a fake account CommanderInfo fakePc; commanderInfoInit(&fakePc); fakePc.pos = session->game.commanderSession.currentCommander.info.pos; fakePc.appearance.accountId = r1emuGenerateRandom64(&self->seed); fakePc.socialInfoId = r1emuGenerateRandom64(&self->seed); fakePc.pcId = r1emuGenerateRandom(&self->seed); fakePc.commanderId = r1emuGenerateRandom64(&self->seed); snprintf(fakePc.appearance.familyName, sizeof(fakePc.appearance.familyName), "PcID_%x", fakePc.pcId); snprintf(fakePc.appearance.commanderName, sizeof(fakePc.appearance.commanderName), "AccountID_%llx", fakePc.appearance.accountId); // register the fake socket session SocketSession fakeSocketSession; uint32_t sessionKey = r1emuGenerateRandom(&self->seed); uint8_t sessionKeyStr[SOCKET_SESSION_ID_SIZE]; socketSessionGenSessionKey((uint8_t *)&sessionKey, sessionKeyStr); sprintf(sessionKeyStr, "%.08x", sessionKey); socketSessionInit(&fakeSocketSession, fakePc.appearance.accountId, self->info.routerId, session->socket.mapId, sessionKeyStr, true); RedisSocketSessionKey socketKey = { .routerId = self->info.routerId, .sessionKey = sessionKeyStr }; redisUpdateSocketSession(self->redis, &socketKey, &fakeSocketSession); // register the fake game session GameSession fakeGameSession; gameSessionInit(&fakeGameSession, &fakePc); accountSessionInit(&fakeGameSession.accountSession, "DummyPC", sessionKeyStr, ACCOUNT_SESSION_PRIVILEGES_ADMIN); RedisGameSessionKey gameKey = { .routerId = fakeSocketSession.routerId, .mapId = fakeSocketSession.mapId, .accountId = fakeSocketSession.accountId }; redisUpdateGameSession(self->redis, &gameKey, sessionKeyStr, &fakeGameSession); info("Fake PC spawned.(SocketID=%s, SocialID=%I64x, AccID=%I64x, PcID=%x, CommID=%I64x)", sessionKeyStr, fakePc.socialInfoId, fakePc.appearance.accountId, fakePc.pcId, fakePc.commanderId); GameEventEnterPc event = { .updatePosEvent = { .mapId = fakeSocketSession.mapId, .info = fakePc } }; workerDispatchEvent(self, sessionKeyStr, EVENT_TYPE_ENTER_PC, &event, sizeof(event)); } void adminCmdAddItem(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { uint32_t itemId = strtol(args, &args, 10); args++; uint32_t amount = strtol(args, &args, 10); uint32_t itemPosition = 1; ItemPkt item = { .uniqueId = r1emuGenerateRandom64(&self->seed), .amount = (!amount) ? 1 : amount, .inventoryIndex = INVENTORY_CAT_SIZE * INVENTORY_CAT_CONSUMABLE + itemPosition, .id = itemId }; zoneBuilderItemAdd(&item, INVENTORY_ADD_PICKUP, replyMsg); } void adminCmdJump(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Jump without argument!"); // we must add a random with the map max x/y } else { char **arg; int argc; info("Jump with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 3) { info("Wrong number of argument, must be 3."); } else { PositionXYZ position; position.x = atof(arg[0]); info("x = %.6f", position.x); position.y = atof(arg[1]); info("y = %.6f", position.y); position.z = atof(arg[2]); info("z = %.6f", position.z); session->game.commanderSession.currentCommander.info.pos = position; zoneBuilderSetPos(session->game.commanderSession.currentCommander.info.pcId, &position, replyMsg); } free(arg); } } void adminCmdTest(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { info("Test command launched."); size_t memSize; void *memory = dumpToMem( "[03:12:32][main.c:30 in writePacketToFile] E9 0C 73 2A 86 02 35 00 A2 4E 00 00 02 01 05 00 | ..s*..5..N......\n" "[03:12:32][main.c:30 in writePacketToFile] 4E 61 6D 65 00 0C 00 44 61 72 6B 48 6F 72 69 7A | Name...DarkHoriz\n" "[03:12:32][main.c:30 in writePacketToFile] 6F 6E 00 04 00 57 68 6F 00 0A 00 4C 6F 74 68 62 | on...Who...Lothb\n" "[03:12:32][main.c:30 in writePacketToFile] 72 6F 6F 6B 00 | rook." , NULL, &memSize ); zmsg_add(replyMsg, zframe_new(memory, memSize)); } void adminCmdWhere(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { const uint16_t MAX_LEN = 128; char message[MAX_LEN]; PositionXYZ position; position = session->game.commanderSession.currentCommander.info.pos; snprintf(message, sizeof(message), "[%hu] x = %.0f, y = %.0f, z = %.0f", session->game.commanderSession.mapId, position.x, position.y, position.z); zoneBuilderChat(&session->game.commanderSession.currentCommander.info, message, replyMsg); } void adminCmdChangeCamera(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { const uint16_t MAX_LEN = 128; char message[MAX_LEN]; PositionXYZ pos; float fspd; float ispd; info("Change Camera command used, args = %s", args); if (strlen (args) == 0) { pos.x = 0; pos.y = 0; pos.z = 0; zoneBuilderChangeCamera((uint8_t)0, &pos, (float)0, (float)0, replyMsg); } else { char **arg; int argc; arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc >= 3) { pos.x = (strlen(arg[0]) == 1 && arg[0][0] == 'c') ? session->game.commanderSession.currentCommander.info.pos.x : atof(arg[0]); pos.y = (strlen(arg[1]) == 1 && arg[1][0] == 'c') ? session->game.commanderSession.currentCommander.info.pos.y : atof(arg[1]); pos.z = (strlen(arg[2]) == 1 && arg[2][0] == 'c') ? session->game.commanderSession.currentCommander.info.pos.z : atof(arg[2]); } if (argc == 3) zoneBuilderChangeCamera((uint8_t)1, &pos, (float)10, (float)0.7, replyMsg); else if (argc == 5) { fspd = atof(arg[3]); ispd = atof(arg[4]); zoneBuilderChangeCamera((uint8_t)1, &pos, fspd, ispd, replyMsg); } else { snprintf(message, sizeof(message), "Bad usage /changeCamera <x> <y> <z> {<fspd> <ispd>}"); zoneBuilderChat(&session->game.commanderSession.currentCommander.info, message, replyMsg); } free(arg); } } void adminCmdSetStamina(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Set stamina needs a argument!"); } else { char **arg; int argc; info("Set stamina with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 1) { info("Wrong number of arguments, must be 1."); } else { uint32_t stamina = atoi(arg[0]) * 1000; info("Setting stamina to %d.", stamina); session->game.commanderSession.currentCommander.info.currentStamina = stamina; zoneBuilderStamina(stamina, replyMsg); } free(arg); } } void adminCmdSetSP(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Set SP needs a argument!"); } else { char **arg; int argc; info("Set SP with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 1) { info("Wrong number of arguments, must be 1."); } else { uint32_t sp = atoi(arg[0]); info("Setting SP to %d.", sp); session->game.commanderSession.currentCommander.info.currentSP = sp; zoneBuilderUpdateSP(session->game.commanderSession.currentCommander.info.pcId, sp, replyMsg); } free(arg); } } void adminCmdSetLevel(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Set level needs a argument!"); } else { char **arg; int argc; info("Set level with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 1) { info("Wrong number of arguments, must be 1."); } else { uint32_t level = atoi(arg[0]); info("Setting level to %d.", level); session->game.commanderSession.currentCommander.info.appearance.level = level; zoneBuilderPCLevelUp(session->game.commanderSession.currentCommander.info.pcId, level, replyMsg); } free(arg); } }
bool redisGetSession (Redis *self, RedisSessionKey *key, Session *session) { GameSession *gameSession = &session->game; SocketSession *socketSession = &session->socket; AccountSession *accountSession = &gameSession->accountSession; RedisSocketSessionKey *socketKey = &key->socketKey; // Search for the Socket Session if (!redisGetSocketSession(self, socketKey, socketSession)) { error("Cannot get Socket Session."); return false; } if (!socketSession->authenticated) { // This is the first time the client connect. // Initialize an empty game session CommanderInfo commanderInfo; commanderInfoInit (&commanderInfo); gameSessionInit (gameSession, &commanderInfo); dbg("Welcome, SOCKET_%s ! A new session has been initialized for you.", socketKey->sessionKey); } else { // Get account session RedisAccountSessionKey accountKey = { .accountId = socketSession->accountId }; if (!redisGetAccountSession(self, &accountKey, accountSession)) { error("Cannot get Account Session."); return false; } // The client already exist in the game, get Game Session RedisGameSessionKey gameKey = { .routerId = socketSession->routerId, .mapId = socketSession->mapId, .accountId = socketSession->accountId }; if (!redisGetGameSession(self, &gameKey, gameSession)) { error("Cannot get Game Session."); return false; } // dbg("Welcome back, SOCKET_%s !", sessionKey); } return true; } bool redisUpdateSession (Redis *self, Session *session) { RedisSocketSessionKey socketKey = { .routerId = session->socket.routerId, .sessionKey = session->socket.sessionKey }; if (!redisUpdateSocketSession (self, &socketKey, &session->socket)) { error("Cannot update the socket session."); return false; } RedisGameSessionKey gameKey = { .routerId = session->socket.routerId, .mapId = session->socket.mapId, .accountId = session->socket.accountId }; if (!(redisUpdateGameSession(self, &gameKey, session->socket.sessionKey, &session->game))) { error("Cannot update the game session"); return false; } if (session->socket.accountId > 0) { RedisAccountSessionKey accountKey = { .accountId = session->socket.accountId }; if (!(redisUpdateAccountSession(self, &accountKey, &session->game.accountSession))) { error("Cannot update the account session"); return false; } } return true; } bool redisFlushSession (Redis *self, RedisSessionKey *key) { RedisSocketSessionKey *socketKey = &key->socketKey; // Retrieve the entire SocketSession SocketSession socketSession; if (!(redisGetSocketSession(self, socketKey, &socketSession))) { error("Cannot get the SocketSession for %s.", socketKey->sessionKey); return false; } // Flush Account Session RedisAccountSessionKey accountKey = { .accountId = socketSession.accountId }; if (!(redisFlushAccountSession (self, &accountKey))) { error("Cannot flush the Account Session associated with the Socket Session."); return false; } // Flush the game session RedisGameSessionKey gameKey = { .routerId = socketSession.routerId, .mapId = socketSession.mapId, .accountId = socketSession.accountId }; if (!(redisFlushGameSession (self, &gameKey))) { error("Cannot flush the Game Session associated with the Socket Session."); return false; } // Flush the socket session if (!(redisFlushSocketSession (self, socketKey))) { error("Cannot flush the Game Session associated with the Socket Session."); return false; } return true; }
void adminCmdSpawnPc(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { // add a fake commander with a fake account Commander fakePc; commanderInit(&fakePc); fakePc.pos = session->game.commanderSession.currentCommander->pos; fakePc.dir = session->game.commanderSession.currentCommander->dir; fakePc.accountId = r1emuGenerateRandom64(&self->seed); fakePc.socialInfoId = r1emuGenerateRandom64(&self->seed); fakePc.pcId = r1emuGenerateRandom(&self->seed); fakePc.commanderId = r1emuGenerateRandom64(&self->seed); snprintf(fakePc.familyName, sizeof(fakePc.familyName), "PcID_%x", fakePc.pcId); snprintf(fakePc.commanderName, sizeof(fakePc.commanderName), "AccountID_%llx", fakePc.accountId); // register the fake socket session SocketSession fakeSocketSession; uint32_t sessionKey = r1emuGenerateRandom(&self->seed); uint8_t sessionKeyStr[SOCKET_SESSION_ID_SIZE]; socketSessionGenSessionKey((uint8_t *)&sessionKey, sessionKeyStr); sprintf(sessionKeyStr, "%.08x", sessionKey); socketSessionInit(&fakeSocketSession, fakePc.accountId, self->info.routerId, session->socket.mapId, sessionKeyStr, true); RedisSocketSessionKey socketKey = { .routerId = self->info.routerId, .sessionKey = sessionKeyStr }; redisUpdateSocketSession(self->redis, &socketKey, &fakeSocketSession); // register the fake game session GameSession fakeGameSession; gameSessionInit(&fakeGameSession, &fakePc); accountSessionInit(&fakeGameSession.accountSession, "DummyPC", sessionKeyStr, ACCOUNT_SESSION_PRIVILEGES_ADMIN); RedisGameSessionKey gameKey = { .routerId = fakeSocketSession.routerId, .mapId = fakeSocketSession.mapId, .accountId = fakeSocketSession.accountId }; redisUpdateGameSession(self->redis, &gameKey, sessionKeyStr, &fakeGameSession); info("Fake PC spawned.(SocketID=%s, SocialID=%I64x, AccID=%I64x, PcID=%x, CommID=%I64x)", sessionKeyStr, fakePc.socialInfoId, fakePc.accountId, fakePc.pcId, fakePc.commanderId); GameEventEnterPc event = { .updatePosEvent = { .mapId = fakeSocketSession.mapId, .commander = fakePc } }; workerDispatchEvent(self, sessionKeyStr, EVENT_TYPE_ENTER_PC, &event, sizeof(event)); } void adminCmdAddItem(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { Item *newItem = NULL; ItemId_t itemId = strtol(args, &args, 10); args++; ItemAmount_t amount = strtol(args, &args, 10); amount = amount ? amount : 1; // Create new item if (!(newItem = itemFactoryCreate(itemId, amount))) { error("Item ID = %d is invalid.", itemId); return; } Inventory *inventory = &session->game.commanderSession.currentCommander->inventory; inventoryAddItem(inventory, newItem); ItemCategory_t itemCategory = itemGetCategory(newItem); ActorId_t actorId = actorGetUId(newItem); dbg("itemCategory %d", itemCategory); ItemInventoryIndex_t inventoryIndex = inventoryGetBagIndexByActorId(inventory, itemCategory, actorId); dbg("inventoryIndex %d", inventoryIndex); zoneBuilderItemAdd(newItem, inventoryIndex, INVENTORY_ADD_PICKUP, replyMsg); } void adminCmdAddSkill(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { SkillId_t skillId = strtol(args, &args, 10); args++; SkillLevel_t level = strtol(args, &args, 10); skillId = skillId ? skillId : 40001; // Heal level = level ? level : 1; SkillsManager *skillsManager = &session->game.commanderSession.currentCommander->skillsManager; /* Item *newItem = itemFactoryCreate(itemId, amount); skillsManagerAddskill(skillsManager, newItem); ItemCategory_t itemCategory = itemGetCategory(newItem); ActorId_t actorId = actorGetUId(newItem); dbg("itemCategory %d", itemCategory); ItemInventoryIndex_t inventoryIndex = inventoryGetBagIndexByActorId(inventory, itemCategory, actorId); dbg("inventoryIndex %d", inventoryIndex); */ zoneBuilderSkillAdd(skillId, replyMsg); }