예제 #1
0
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;
}
예제 #2
0
파일: session.c 프로젝트: Quinchu/R1EMU
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;
}
예제 #3
0
파일: admin_cmd.c 프로젝트: kkourin/R1EMU
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);
    }
}
예제 #4
0
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;
}
예제 #5
0
파일: admin_cmd.c 프로젝트: eduardjr/R1EMU
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);
}