From 11ae3d0e42293d01b4d729ed5b6fceb8f0ec3fa5 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Tue, 1 Jul 2025 15:39:01 -0300 Subject: merged `dbfuncs.cc` into `crplayer.cc` --- TODO.md | 1 - reference/enums.hh | 10 - reference/game.c | 735 ----------------------------------------------------- src/cr.hh | 2 +- src/crplayer.cc | 506 ++++++++++++++++++++++++++++++++++++ src/main.cc | 6 +- src/operate.hh | 14 + 7 files changed, 523 insertions(+), 751 deletions(-) delete mode 100644 reference/enums.hh diff --git a/TODO.md b/TODO.md index 896d08d..ab216b8 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,4 @@ ## TODO NEXT -- DBFUNCS.CC - QUERY.CC - Include `x == 0xFFFF` inside `CheckVisibility`? diff --git a/reference/enums.hh b/reference/enums.hh deleted file mode 100644 index 47d5196..0000000 --- a/reference/enums.hh +++ /dev/null @@ -1,10 +0,0 @@ -enum CHANNEL: int { - GUILD_CHANNEL=0, - GAMEMASTER_CHANNEL=1, - TUTOR_CHANNEL=2, - REQUEST_QUEUE=3, - GAME_CHANNEL=4, - TRADE_CHANNEL=5, - REALLIFE_CHANNEL=6, - HELP_CHANNEL=7 -}; diff --git a/reference/game.c b/reference/game.c index 955fb2a..db75c28 100644 --- a/reference/game.c +++ b/reference/game.c @@ -1,738 +1,3 @@ -// DBFUNCS.CC -> PLAYERLOADER.CC ? -//============================================================================== - -// WARNING: Unknown calling convention -- yet parameter storage is locked - -void PlayerDataPath(void) - -{ - uint in_stack_00000004; - char *in_stack_0000000c; - - sprintf(in_stack_0000000c,"%s/%02ld/%ld.%s",USERPATH,in_stack_00000004 % 100); - return; -} - - - -bool PlayerDataExists(ulong CharacterID) - -{ - bool bVar1; - char local_100c [4]; - char FileName [4096]; - - sprintf(local_100c,"%s/%02ld/%ld.%s",USERPATH,CharacterID % 100,CharacterID,&DAT_080f6560); - bVar1 = FileExists(local_100c); - return bVar1; -} - - - -// WARNING: Removing unreachable block (ram,0x0806d081) -// WARNING: Removing unreachable block (ram,0x0806d0da) -// WARNING: Removing unreachable block (ram,0x0806d08b) -// WARNING: Removing unreachable block (ram,0x0806d095) -// WARNING: Removing unreachable block (ram,0x0806d0c7) -// WARNING: Removing unreachable block (ram,0x0806d0a0) - -bool LoadPlayerData(TPlayerData *Slot) - -{ - bool bVar1; - char cVar2; - int SkillNr; - int iVar3; - uint uVar4; - int iVar5; - uchar *puVar6; - anon_union_4_2_730cd3ca_for_TOutfit_2 *paVar7; - int DepotNr; - int SkillNr_2; - int *piVar8; - char *pcVar9; - undefined1 uVar10; - char *pcVar11; - undefined1 auStack_500c [3]; - bool FileOk; - TReadScriptFile Script; - undefined1 local_102c [4]; - TDynamicWriteBuffer HelpBuffer; - char FileName [4096]; - - if (Slot == (TPlayerData *)0x0) { - pcVar11 = "LoadPlayerData: Slot ist NULL.\n"; - } - else { - uVar4 = Slot->CharacterID; - if (uVar4 != 0) { - piVar8 = &HelpBuffer.super_TWriteBuffer.Position; - pcVar11 = USERPATH; - sprintf((char *)piVar8,"%s/%02ld/%ld.%s",USERPATH,uVar4 % 100,uVar4,&DAT_080f6560); - bVar1 = FileExists((char *)piVar8); - if (!bVar1) { - Slot->Race = 1; - iVar3 = 0; - Slot->Profession = 0; - (Slot->OriginalOutfit).OutfitID = 0; - (Slot->OriginalOutfit).field_1 = (anon_union_4_2_730cd3ca_for_TOutfit_2)0x0; - (Slot->CurrentOutfit).OutfitID = 0; - (Slot->CurrentOutfit).field_1 = (anon_union_4_2_730cd3ca_for_TOutfit_2)0x0; - Slot->LastLoginTime = 0; - Slot->LastLogoutTime = 0; - Slot->startx = 0; - Slot->starty = 0; - Slot->startz = 0; - Slot->posx = 0; - Slot->posy = 0; - Slot->posz = 0; - Slot->PlayerkillerEnd = 0; - do { - Slot->Minimum[iVar3] = -0x80000000; - iVar3 = iVar3 + 1; - } while (iVar3 < 0x19); - puVar6 = Slot->SpellList; - for (iVar3 = 0x40; iVar3 != 0; iVar3 = iVar3 + -1) { - puVar6[0] = '\0'; - puVar6[1] = '\0'; - puVar6[2] = '\0'; - puVar6[3] = '\0'; - puVar6 = puVar6 + 4; - } - uVar4 = 2000; - piVar8 = Slot->QuestValues; - if (((uint)piVar8 & 4) != 0) { - piVar8 = Slot->QuestValues + 1; - uVar4 = 0x7cc; - Slot->QuestValues[0] = 0; - } - for (uVar4 = uVar4 >> 2; uVar4 != 0; uVar4 = uVar4 - 1) { - *piVar8 = 0; - piVar8 = piVar8 + 1; - } - Slot->MurderTimestamps[0] = 0; - Slot->MurderTimestamps[1] = 0; - Slot->MurderTimestamps[2] = 0; - Slot->MurderTimestamps[3] = 0; - Slot->MurderTimestamps[4] = 0; - Slot->MurderTimestamps[5] = 0; - Slot->MurderTimestamps[6] = 0; - Slot->MurderTimestamps[8] = 0; - Slot->MurderTimestamps[9] = 0; - Slot->MurderTimestamps[10] = 0; - Slot->MurderTimestamps[0xb] = 0; - Slot->MurderTimestamps[0xc] = 0; - Slot->MurderTimestamps[7] = 0; - Slot->MurderTimestamps[0xd] = 0; - Slot->MurderTimestamps[0xe] = 0; - Slot->MurderTimestamps[0xf] = 0; - Slot->MurderTimestamps[0x10] = 0; - Slot->InventorySize = 0; - iVar3 = 0; - Slot->MurderTimestamps[0x11] = 0; - Slot->MurderTimestamps[0x12] = 0; - Slot->MurderTimestamps[0x13] = 0; - Slot->Inventory = (uchar *)0x0; - do { - Slot->Depot[iVar3] = (uchar *)0x0; - Slot->DepotSize[iVar3] = 0; - iVar3 = iVar3 + 1; - } while (iVar3 < 9); - return true; - } - TDynamicWriteBuffer::TDynamicWriteBuffer((TDynamicWriteBuffer *)local_102c,0x4000); - // try { // try from 0806c499 to 0806c49d has its CatchHandler @ 0806d1cf - TReadScriptFile::TReadScriptFile((TReadScriptFile *)auStack_500c); - // try { // try from 0806c4ab to 0806c5b3 has its CatchHandler @ 0806d1c6 - TReadScriptFile::open((TReadScriptFile *)auStack_500c,(char *)piVar8,(int)pcVar11); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - pcVar11 = TReadScriptFile::readString((TReadScriptFile *)auStack_500c); - strcpy(Slot->Name,pcVar11); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Race = iVar3; - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Profession = iVar3; - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - // try { // try from 0806c5c8 to 0806c626 has its CatchHandler @ 0806d12c - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'('); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - (Slot->OriginalOutfit).OutfitID = iVar3; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - if ((Slot->OriginalOutfit).OutfitID == 0) { - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - (Slot->OriginalOutfit).field_1.ObjectType = (ushort)iVar3; - } - else { - // try { // try from 0806d10d to 0806d111 has its CatchHandler @ 0806d12c - paVar7 = (anon_union_4_2_730cd3ca_for_TOutfit_2 *) - TReadScriptFile::readBytesequence((TReadScriptFile *)auStack_500c); - (Slot->OriginalOutfit).field_1 = *paVar7; - } - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,')'); - // try { // try from 0806c630 to 0806c64a has its CatchHandler @ 0806d1c6 - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - // try { // try from 0806c65f to 0806c6bd has its CatchHandler @ 0806d12c - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'('); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - (Slot->CurrentOutfit).OutfitID = iVar3; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - if ((Slot->CurrentOutfit).OutfitID == 0) { - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - (Slot->CurrentOutfit).field_1.ObjectType = (ushort)iVar3; - } - else { - // try { // try from 0806d0f5 to 0806d0f9 has its CatchHandler @ 0806d12c - paVar7 = (anon_union_4_2_730cd3ca_for_TOutfit_2 *) - TReadScriptFile::readBytesequence((TReadScriptFile *)auStack_500c); - (Slot->CurrentOutfit).field_1 = *paVar7; - } - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,')'); - // try { // try from 0806c6c7 to 0806d062 has its CatchHandler @ 0806d1c6 - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->LastLoginTime = iVar3; - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->LastLogoutTime = iVar3; - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readCoordinate((TReadScriptFile *)auStack_500c); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readCoordinate((TReadScriptFile *)auStack_500c); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->PlayerkillerEnd = iVar3; - iVar3 = 0; - do { - Slot->Minimum[iVar3] = -0x80000000; - iVar3 = iVar3 + 1; - uVar10 = iVar3 == 0x18; - } while (iVar3 < 0x19); - do { - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - pcVar11 = TReadScriptFile::getIdentifier((TReadScriptFile *)auStack_500c); - iVar3 = 6; - pcVar9 = "skill"; - do { - if (iVar3 == 0) break; - iVar3 = iVar3 + -1; - uVar10 = *pcVar11 == *pcVar9; - pcVar11 = pcVar11 + 1; - pcVar9 = pcVar9 + 1; - } while ((bool)uVar10); - if (!(bool)uVar10) goto LAB_0806cb0a; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'('); - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - bVar1 = false; - if ((-1 < iVar3) && (iVar3 < 0x19)) { - bVar1 = true; - } - uVar10 = !bVar1; - if ((bool)uVar10) { - TReadScriptFile::error((TReadScriptFile *)auStack_500c,"illegal skill number"); - } - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Actual[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Maximum[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Minimum[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->DeltaAct[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->MagicDeltaAct[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Cycle[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->MaxCycle[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Count[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->MaxCount[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->AddLevel[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Experience[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->FactorPercent[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->NextLevel[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->Delta[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,')'); - } while( true ); - } - pcVar11 = &DAT_080f6720; - } - error(pcVar11); - return false; -LAB_0806cb0a: - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'{'); -LAB_0806cb3b: - TReadScriptFile::nextToken((TReadScriptFile *)auStack_500c); - if (_auStack_500c != SPECIAL) goto LAB_0806cb7f; - cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c); - if (cVar2 != '}') goto code_r0x0806cb64; - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'{'); - while( true ) { - TReadScriptFile::nextToken((TReadScriptFile *)auStack_500c); - if (_auStack_500c != SPECIAL) goto LAB_0806cc5a; - cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c); - if (cVar2 == '}') break; - if (_auStack_500c != SPECIAL) goto LAB_0806cc5a; - cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c); - if (cVar2 != ',') { - if ((_auStack_500c != SPECIAL) || - (cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c), cVar2 != '(')) - { -LAB_0806cc5a: - TReadScriptFile::error((TReadScriptFile *)auStack_500c,"\'(\' expected"); - } - iVar3 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - bVar1 = false; - if ((-1 < iVar3) && (iVar3 < 500)) { - bVar1 = true; - } - if (!bVar1) { - TReadScriptFile::error((TReadScriptFile *)auStack_500c,"illegal quest number"); - } - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,','); - iVar5 = TReadScriptFile::readNumber((TReadScriptFile *)auStack_500c); - Slot->QuestValues[iVar3] = iVar5; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,')'); - } - } - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'{'); -LAB_0806cd45: - TReadScriptFile::nextToken((TReadScriptFile *)auStack_500c); - if (_auStack_500c != SPECIAL) goto LAB_0806cd89; - cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c); - if (cVar2 != '}') goto code_r0x0806cd6e; - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'{'); - HelpBuffer.super_TWriteBuffer.Size = 0; -LAB_0806cdfa: - TReadScriptFile::nextToken((TReadScriptFile *)auStack_500c); - if (_auStack_500c != SPECIAL) goto LAB_0806ce42; - cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c); - if (cVar2 != '}') goto code_r0x0806ce27; - TDynamicWriteBuffer::writeByte((TDynamicWriteBuffer *)local_102c,0xff); - Slot->InventorySize = HelpBuffer.super_TWriteBuffer.Size; - puVar6 = (uchar *)operator_new__(HelpBuffer.super_TWriteBuffer.Size); - Slot->Inventory = puVar6; - memcpy(puVar6,HelpBuffer.super_TWriteBuffer.super_TWriteStream._vptr_TWriteStream, - Slot->InventorySize); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - pcVar11 = (char *)0x7b; - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'{'); - iVar3 = 0; - do { - Slot->Depot[iVar3] = (uchar *)0x0; - iVar3 = iVar3 + 1; - } while (iVar3 < 9); -LAB_0806cf45: - TReadScriptFile::nextToken((TReadScriptFile *)auStack_500c); - if (_auStack_500c == SPECIAL) goto code_r0x0806cf5c; - goto LAB_0806cf8d; -code_r0x0806cb64: - if ((_auStack_500c != SPECIAL) || - (cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c), cVar2 != ',')) { -LAB_0806cb7f: - iVar3 = TReadScriptFile::getNumber((TReadScriptFile *)auStack_500c); - bVar1 = false; - if ((-1 < iVar3) && (iVar3 < 0x100)) { - bVar1 = true; - } - if (!bVar1) { - TReadScriptFile::error((TReadScriptFile *)auStack_500c,"illegal spell number"); - } - Slot->SpellList[iVar3] = '\x01'; - } - goto LAB_0806cb3b; -code_r0x0806cd6e: - if ((_auStack_500c != SPECIAL) || - (cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c), cVar2 != ',')) { -LAB_0806cd89: - iVar3 = 1; - do { - Slot->MurderTimestamps[iVar3 + -1] = Slot->MurderTimestamps[iVar3]; - iVar3 = iVar3 + 1; - } while (iVar3 < 0x14); - iVar3 = TReadScriptFile::getNumber((TReadScriptFile *)auStack_500c); - Slot->MurderTimestamps[0x13] = iVar3; - } - goto LAB_0806cd45; -code_r0x0806ce27: - if ((_auStack_500c != SPECIAL) || - (cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c), cVar2 != ',')) { -LAB_0806ce42: - iVar3 = TReadScriptFile::getNumber((TReadScriptFile *)auStack_500c); - TDynamicWriteBuffer::writeByte((TDynamicWriteBuffer *)local_102c,(uchar)iVar3); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - LoadObjects((TReadScriptFile *)auStack_500c,(TWriteStream *)local_102c,false); - } - goto LAB_0806cdfa; -code_r0x0806cf5c: - cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c); - if (cVar2 == '}') { - TReadScriptFile::nextToken((TReadScriptFile *)auStack_500c); - if (_auStack_500c != ENDOFFILE) { - pcVar11 = "end of file expected"; - TReadScriptFile::error((TReadScriptFile *)auStack_500c,"end of file expected"); - } - TReadScriptFile::close((TReadScriptFile *)auStack_500c,(int)pcVar11); - // try { // try from 0806d073 to 0806d077 has its CatchHandler @ 0806d1cf - TReadScriptFile::~TReadScriptFile((TReadScriptFile *)auStack_500c,(int)pcVar11); - TDynamicWriteBuffer::~TDynamicWriteBuffer((TDynamicWriteBuffer *)local_102c,(int)pcVar11); - return true; - } - if ((_auStack_500c != SPECIAL) || - (cVar2 = TReadScriptFile::getSpecial((TReadScriptFile *)auStack_500c), cVar2 != ',')) { -LAB_0806cf8d: - iVar3 = TReadScriptFile::getNumber((TReadScriptFile *)auStack_500c); - TReadScriptFile::readIdentifier((TReadScriptFile *)auStack_500c); - TReadScriptFile::readSymbol((TReadScriptFile *)auStack_500c,'='); - HelpBuffer.super_TWriteBuffer.Size = 0; - LoadObjects((TReadScriptFile *)auStack_500c,(TWriteStream *)local_102c,false); - Slot->DepotSize[iVar3] = HelpBuffer.super_TWriteBuffer.Size; - puVar6 = (uchar *)operator_new__(HelpBuffer.super_TWriteBuffer.Size); - Slot->Depot[iVar3] = puVar6; - pcVar11 = (char *)HelpBuffer.super_TWriteBuffer.super_TWriteStream; - memcpy(puVar6,HelpBuffer.super_TWriteBuffer.super_TWriteStream._vptr_TWriteStream, - Slot->DepotSize[iVar3]); - } - goto LAB_0806cf45; -} - - - -void SavePlayerData(TPlayerData *Slot) - -{ - uint uVar1; - bool bVar2; - bool FirstSpell; - byte bVar3; - time_t tVar4; - int Number; - int SpellNr; - int *piVar5; - int Limitation; - int iVar6; - char *pcVar7; - undefined *__fd; - undefined1 local_203c; - bool FirstDepot; - bool FirstPosition; - bool FirstMurder; - TReadBuffer Buffer; - TWriteScriptFile Script; - char local_101c [4]; - char FileName [4096]; - - if (Slot == (TPlayerData *)0x0) { - pcVar7 = "SavePlayerData: Slot ist NULL.\n"; - } - else { - uVar1 = Slot->CharacterID; - if (uVar1 != 0) { - pcVar7 = USERPATH; - sprintf(local_101c,"%s/%02ld/%ld.%s",USERPATH,uVar1 % 100,uVar1,&DAT_080f6560); - // try { // try from 0806d29e to 0806d2a2 has its CatchHandler @ 0806de36 - TWriteScriptFile::TWriteScriptFile((TWriteScriptFile *)&Buffer.Position); - // try { // try from 0806d2b6 to 0806d3b6 has its CatchHandler @ 0806de30 - TWriteScriptFile::open((TWriteScriptFile *)&Buffer.Position,local_101c,(int)pcVar7); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"ID = "); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,Slot->CharacterID); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Name = "); - TWriteScriptFile::writeString((TWriteScriptFile *)&Buffer.Position,Slot->Name); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Race = "); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,Slot->Race); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Profession = "); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,Slot->Profession); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"OriginalOutfit = "); - // try { // try from 0806d3cb to 0806d431 has its CatchHandler @ 0806ddc3 - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"("); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,(Slot->OriginalOutfit).OutfitID); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - if ((Slot->OriginalOutfit).OutfitID == 0) { - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position, - (uint)(Slot->OriginalOutfit).field_1.ObjectType); - } - else { - // try { // try from 0806ddad to 0806ddb1 has its CatchHandler @ 0806ddc3 - TWriteScriptFile::writeBytesequence - ((TWriteScriptFile *)&Buffer.Position, - (Slot->OriginalOutfit).field_1.Colors,4); - } - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,")"); - // try { // try from 0806d43b to 0806d455 has its CatchHandler @ 0806de30 - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"CurrentOutfit = "); - // try { // try from 0806d46a to 0806d4d0 has its CatchHandler @ 0806ddc3 - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"("); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,(Slot->CurrentOutfit).OutfitID); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - if ((Slot->CurrentOutfit).OutfitID == 0) { - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position, - (uint)(Slot->CurrentOutfit).field_1.ObjectType); - } - else { - // try { // try from 0806dd8b to 0806dd8f has its CatchHandler @ 0806ddc3 - TWriteScriptFile::writeBytesequence - ((TWriteScriptFile *)&Buffer.Position,(Slot->CurrentOutfit).field_1.Colors - ,4); - } - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,")"); - // try { // try from 0806d4da to 0806dd20 has its CatchHandler @ 0806de30 - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"LastLogin = "); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,Slot->LastLoginTime); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"LastLogout = "); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,Slot->LastLogoutTime) - ; - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"StartPosition = "); - TWriteScriptFile::writeCoordinate - ((TWriteScriptFile *)&Buffer.Position,Slot->startx,Slot->starty,Slot->startz); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"CurrentPosition = "); - TWriteScriptFile::writeCoordinate - ((TWriteScriptFile *)&Buffer.Position,Slot->posx,Slot->posy,Slot->posz); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"PlayerkillerEnd = "); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,Slot->PlayerkillerEnd); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - iVar6 = 0; - piVar5 = Slot->Delta; - do { - if (piVar5[-0x113] != -0x80000000) { - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Skill = ("); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,iVar6); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0x145]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,piVar5[-300]) - ; - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0x113]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0xfa]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0xe1]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,piVar5[-200]) - ; - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0xaf]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0x96]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0x7d]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,piVar5[-100]) - ; - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0x4b]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0x32]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,piVar5[-0x19]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,*piVar5); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,")"); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - } - iVar6 = iVar6 + 1; - piVar5 = piVar5 + 1; - } while (iVar6 < 0x19); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Spells = {"); - bVar2 = true; - iVar6 = 0; - do { - if (Slot->SpellList[iVar6] != '\0') { - if (!bVar2) { - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - } - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,iVar6); - bVar2 = false; - } - iVar6 = iVar6 + 1; - } while (iVar6 < 0x100); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"}"); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"QuestValues = {"); - bVar2 = true; - iVar6 = 0; - do { - if (Slot->QuestValues[iVar6] != 0) { - if (!bVar2) { - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - } - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"("); - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,iVar6); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeNumber - ((TWriteScriptFile *)&Buffer.Position,Slot->QuestValues[iVar6]); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,")"); - bVar2 = false; - } - iVar6 = iVar6 + 1; - } while (iVar6 < 500); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"}"); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Murders = {"); - bVar2 = true; - iVar6 = 0; - tVar4 = time((time_t *)0x0); - do { - Number = Slot->MurderTimestamps[iVar6]; - if (tVar4 + -0x278d00 < Number) { - if (!bVar2) { - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - Number = Slot->MurderTimestamps[iVar6]; - } - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,Number); - bVar2 = false; - } - iVar6 = iVar6 + 1; - } while (iVar6 < 0x14); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"}"); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Inventory = {"); - if (Slot->Inventory != (uchar *)0x0) { - TReadBuffer::TReadBuffer - ((TReadBuffer *)&local_203c,Slot->Inventory,Slot->InventorySize); - bVar2 = true; - while (bVar3 = TReadBuffer::readByte((TReadBuffer *)&local_203c), bVar3 != 0xff) { - if (bVar2) { - bVar2 = false; - } - else { - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,","); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText - ((TWriteScriptFile *)&Buffer.Position," "); - } - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,(uint)bVar3); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position," Content="); - SaveObjects((TReadStream *)&local_203c,(TWriteScriptFile *)&Buffer.Position); - } - } - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"}"); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"Depots = {"); - bVar2 = true; - iVar6 = 0; - do { - if (Slot->Depot[iVar6] != (uchar *)0x0) { - if (bVar2) { - bVar2 = false; - } - else { - // try { // try from 0806dd45 to 0806dd6d has its CatchHandler @ 0806de30 - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,", "); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::writeText - ((TWriteScriptFile *)&Buffer.Position," "); - } - TWriteScriptFile::writeNumber((TWriteScriptFile *)&Buffer.Position,iVar6); - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position," Content="); - TReadBuffer::TReadBuffer - ((TReadBuffer *)&local_203c,Slot->Depot[iVar6],Slot->DepotSize[iVar6]) - ; - SaveObjects((TReadStream *)&local_203c,(TWriteScriptFile *)&Buffer.Position); - } - iVar6 = iVar6 + 1; - } while (iVar6 < 9); - __fd = &DAT_080f2aa0; - TWriteScriptFile::writeText((TWriteScriptFile *)&Buffer.Position,"}"); - TWriteScriptFile::writeLn((TWriteScriptFile *)&Buffer.Position); - TWriteScriptFile::close((TWriteScriptFile *)&Buffer.Position,(int)__fd); - // try { // try from 0806dd2a to 0806dd2e has its CatchHandler @ 0806de36 - TWriteScriptFile::~TWriteScriptFile((TWriteScriptFile *)&Buffer.Position,(int)__fd); - return; - } - pcVar7 = &DAT_080f6800; - } - error(pcVar7); - return; -} - - - -void UnlinkPlayerData(ulong CharacterID) - -{ - char local_100c [4]; - char FileName [4096]; - - sprintf(local_100c,"%s/%02ld/%ld.%s",USERPATH,CharacterID % 100,CharacterID,&DAT_080f6560); - unlink(local_100c); - return; -} - // QUERY.CC //============================================================================== diff --git a/src/cr.hh b/src/cr.hh index e095903..0848d42 100644 --- a/src/cr.hh +++ b/src/cr.hh @@ -956,7 +956,7 @@ int GetRaceSummonCost(int Race); int GetRacePoison(int Race); bool GetRaceUnpushable(int Race); TOutfit ReadOutfit(TReadScriptFile *Script); -void WriteOutfit(TReadScriptFile *Script, TOutfit Outfit); +void WriteOutfit(TWriteScriptFile *Script, TOutfit Outfit); void LoadRace(const char *FileName); void LoadRaces(void); diff --git a/src/crplayer.cc b/src/crplayer.cc index b8e1926..a53e676 100644 --- a/src/crplayer.cc +++ b/src/crplayer.cc @@ -2104,6 +2104,512 @@ void SendExistingRequests(TConnection *Connection){ delete []Players; } +// Player Loader +// ============================================================================= +void PlayerDataPath(char *Buffer, int BufferSize, uint32 CharacterID){ + snprintf(Buffer, BufferSize, "%s/%02u/%u.usr", + USERPATH, (CharacterID % 100), CharacterID); +} + +bool PlayerDataExists(uint32 CharacterID){ + char FileName[4096]; + PlayerDataPath(FileName, sizeof(FileName), CharacterID); + return FileExists(FileName); +} + +bool LoadPlayerData(TPlayerData *Slot){ + if(Slot == NULL){ + error("LoadPlayerData: Slot ist NULL.\n"); + return false; + } + + if(Slot->CharacterID == 0){ + error("LoadPlayerData: Slot enthält keinen Charakter.\n"); + return false; + } + + // IMPORTANT(fusion): This function is only called from `AssignPlayerPoolSlot` + // which zero initializes it before hand. Note that it would be a problem + // otherwise, since we shouldn't write to `CharacterID`, `Locked`, or `Sticky` + // outside a critical section, making `memset` not viable and turning this + // into an assignment fiesta for no good reason. + Slot->Race = 1; + Slot->Profession = PROFESSION_NONE; + for(int SkillNr = 0; + SkillNr < NARRAY(Slot->Minimum); + SkillNr += 1){ + // NOTE(fusion): See `TPlayer::LoadData`. + Slot->Minimum[SkillNr] = INT_MIN; + } + + // NOTE(fusion): First login. Use defaults. + char FileName[4096]; + PlayerDataPath(FileName, sizeof(FileName), Slot->CharacterID); + if(!FileExists(FileName)){ + return true; + } + + bool Result = false; + try{ + // TODO(fusion): Same thing as house loaders. Data is expected to be in + // an exact order and we don't check identifiers + TDynamicWriteBuffer HelpBuffer(KB(16)); + TReadScriptFile Script; + Script.open(FileName); + + Script.readIdentifier(); // "id" + Script.readSymbol('='); + Script.readNumber(); + + Script.readIdentifier(); // "name" + Script.readSymbol('='); + strcpy(Slot->Name, Script.readString()); + + Script.readIdentifier(); // "race" + Script.readSymbol('='); + Slot->Race = Script.readNumber(); + + Script.readIdentifier(); // "profession" + Script.readSymbol('='); + Slot->Profession = (uint8)Script.readNumber(); + + Script.readIdentifier(); // "originaloutfit" + Script.readSymbol('='); + Slot->OriginalOutfit = ReadOutfit(&Script); + + Script.readIdentifier(); // "currentoutfit" + Script.readSymbol('='); + Slot->CurrentOutfit = ReadOutfit(&Script); + + Script.readIdentifier(); // "lastlogin" + Script.readSymbol('='); + Slot->LastLoginTime = (time_t)Script.readNumber(); + + Script.readIdentifier(); // "lastlogout" + Script.readSymbol('='); + Slot->LastLogoutTime = (time_t)Script.readNumber(); + + Script.readIdentifier(); // "startposition" + Script.readSymbol('='); + Script.readCoordinate(&Slot->startx, &Slot->starty, &Slot->startz); + + Script.readIdentifier(); // "currentposition" + Script.readSymbol('='); + Script.readCoordinate(&Slot->posx, &Slot->posy, &Slot->posz); + + Script.readIdentifier(); // "playerkillerend" + Script.readSymbol('='); + Slot->PlayerkillerEnd = Script.readNumber(); + + while(strcmp(Script.readIdentifier(), "skill") == 0){ + Script.readSymbol('='); + Script.readSymbol('('); + int SkillNr = Script.readNumber(); + if(SkillNr < 0 || SkillNr >= NARRAY(Slot->Minimum)){ + Script.error("illegal skill number"); + } + Script.readSymbol(','); + Slot->Actual[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->Maximum[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->Minimum[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->DeltaAct[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->MagicDeltaAct[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->Cycle[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->MaxCycle[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->Count[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->MaxCount[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->AddLevel[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->Experience[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->FactorPercent[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->NextLevel[SkillNr] = Script.readNumber(); + Script.readSymbol(','); + Slot->Delta[SkillNr] = Script.readNumber(); + Script.readSymbol(')'); + } + + // "spells", already primed in the loop condition above + Script.readSymbol('='); + Script.readSymbol('{'); + while(true){ + Script.nextToken(); + if(Script.Token == SPECIAL){ + if(Script.getSpecial() == '}'){ + break; + }else if(Script.getSpecial() == ','){ + continue; + } + } + + int SpellNr = Script.getNumber(); + if(SpellNr < 0 || SpellNr >= NARRAY(Slot->SpellList)){ + Script.error("illegal spell number"); + } + + Slot->SpellList[SpellNr] = 1; + } + + Script.readIdentifier(); // "questvalues" + Script.readSymbol('='); + Script.readSymbol('{'); + while(true){ + char Special = Script.readSpecial(); + if(Special == '}'){ + break; + }else if(Special == ','){ + continue; + }else if(Special != '('){ + Script.error("'(' expected"); + } + + int QuestNr = Script.readNumber(); + if(QuestNr < 0 || QuestNr >= NARRAY(Slot->QuestValues)){ + Script.error("illegal quest number"); + } + Script.readSymbol(','); + Slot->QuestValues[QuestNr] = Script.readNumber(); + Script.readSymbol(')'); + } + + Script.readIdentifier(); // "murders" + Script.readSymbol('='); + Script.readSymbol('{'); + while(true){ + Script.nextToken(); + if(Script.Token == SPECIAL){ + if(Script.getSpecial() == '}'){ + break; + }else if(Script.getSpecial() == ','){ + continue; + } + } + + for(int i = 1; i < NARRAY(Slot->MurderTimestamps); i += 1){ + Slot->MurderTimestamps[i - 1] = Slot->MurderTimestamps[i]; + } + + Slot->MurderTimestamps[NARRAY(Slot->MurderTimestamps) - 1] = Script.getNumber(); + } + + HelpBuffer.Position = 0; + Script.readIdentifier(); // "inventory" + Script.readSymbol('='); + Script.readSymbol('{'); + while(true){ + Script.nextToken(); + if(Script.Token == SPECIAL){ + if(Script.getSpecial() == '}'){ + break; + }else if(Script.getSpecial() == ','){ + continue; + } + } + + int Position = Script.readNumber(); + if(Position < INVENTORY_FIRST || Position > INVENTORY_LAST){ + Script.error("illegal inventory position"); + } + + Script.readIdentifier(); // "content" + Script.readSymbol('='); + HelpBuffer.writeByte((uint8)Position); + LoadObjects(&Script, &HelpBuffer, false); + } + HelpBuffer.writeByte(0xFF); + Slot->Inventory = new uint8[HelpBuffer.Position]; + Slot->InventorySize = HelpBuffer.Position; + memcpy(Slot->Inventory, HelpBuffer.Data, HelpBuffer.Position); + + Script.readIdentifier(); // "depots" + Script.readSymbol('='); + Script.readSymbol('{'); + while(true){ + Script.nextToken(); + if(Script.Token == SPECIAL){ + if(Script.getSpecial() == '}'){ + break; + }else if(Script.getSpecial() == ','){ + continue; + } + } + + int DepotNr = Script.readNumber(); + if(DepotNr < 0 || DepotNr >= NARRAY(Slot->Depot)){ + Script.error("illegal depot number"); + } + + Script.readIdentifier(); // "content" + Script.readSymbol('='); + HelpBuffer.Position = 0; + LoadObjects(&Script, &HelpBuffer, false); + Slot->Depot[DepotNr] = new uint8[HelpBuffer.Position]; + Slot->DepotSize[DepotNr] = HelpBuffer.Position; + memcpy(Slot->Depot[DepotNr], HelpBuffer.Data, HelpBuffer.Position); + } + + Script.nextToken(); + if(Script.Token != ENDOFFILE){ + Script.error("end of file expected"); + } + + Result = true; + }catch(const char *str){ + error("LoadPlayerData: Kann Gegenstände des Spielers %u nicht laden.\n", + Slot->CharacterID); + error("# Fehler: %s\n", str); + }catch(const std::bad_alloc &e){ + error("LoadPlayerData: Kein Speicher frei beim Laden von Spieler %u.\n", + Slot->CharacterID); + } + + if(!Result){ + delete[] Slot->Inventory; + Slot->Inventory = NULL; + Slot->InventorySize = 0; + + for(int DepotNr = 0; + DepotNr < NARRAY(Slot->Depot); + DepotNr += 1){ + delete[] Slot->Depot[DepotNr]; + Slot->Depot[DepotNr] = NULL; + Slot->DepotSize[DepotNr] = 0; + } + } + + return Result; +} + +void SavePlayerData(TPlayerData *Slot){ + if(Slot == NULL){ + error("SavePlayerData: Slot ist NULL.\n"); + return; + } + + if(Slot->CharacterID == 0){ + error("SavePlayerData: Slot enthält keinen Charakter.\n"); + return; + } + + // TODO(fusion): This is prone to problems if we don't backup user files. + // Even if we did automatic backups, would only this user get rolled back? + // This is probably one of the sources of whole day rollbacks. + char FileName[4096]; + PlayerDataPath(FileName, sizeof(FileName), Slot->CharacterID); + try{ + TWriteScriptFile Script; + Script.open(FileName); + + Script.writeText("ID = "); + Script.writeNumber(Slot->CharacterID); + Script.writeLn(); + + Script.writeText("Name = "); + Script.writeString(Slot->Name); + Script.writeLn(); + + Script.writeText("Race = "); + Script.writeNumber(Slot->Race); + Script.writeLn(); + + Script.writeText("Profession = "); + Script.writeNumber(Slot->Profession); + Script.writeLn(); + + Script.writeText("OriginalOutfit = "); + WriteOutfit(&Script, Slot->OriginalOutfit); + Script.writeLn(); + + Script.writeText("CurrentOutfit = "); + WriteOutfit(&Script, Slot->CurrentOutfit); + Script.writeLn(); + + Script.writeText("LastLogin = "); + Script.writeNumber((int)Slot->LastLoginTime); + Script.writeLn(); + + Script.writeText("LastLogout = "); + Script.writeNumber((int)Slot->LastLogoutTime); + Script.writeLn(); + + Script.writeText("StartPosition = "); + Script.writeCoordinate(Slot->startx, Slot->starty, Slot->startz); + Script.writeLn(); + + Script.writeText("CurrentPosition = "); + Script.writeCoordinate(Slot->posx, Slot->posy, Slot->posz); + Script.writeLn(); + + Script.writeText("PlayerkillerEnd = "); + Script.writeNumber(Slot->PlayerkillerEnd); + Script.writeLn(); + Script.writeLn(); + + for(int SkillNr = 0; + SkillNr < NARRAY(Slot->Minimum); + SkillNr += 1){ + if(Slot->Minimum[SkillNr] == INT_MIN){ + continue; + } + + Script.writeText("Skill = ("); + Script.writeNumber(SkillNr); + Script.writeText(","); + Script.writeNumber(Slot->Actual[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->Maximum[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->Minimum[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->DeltaAct[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->MagicDeltaAct[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->Cycle[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->MaxCycle[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->Count[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->MaxCount[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->AddLevel[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->Experience[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->FactorPercent[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->NextLevel[SkillNr]); + Script.writeText(","); + Script.writeNumber(Slot->Delta[SkillNr]); + Script.writeText(")"); + Script.writeLn(); + } + Script.writeLn(); + + bool FirstSpell = true; + Script.writeText("Spells = {"); + for(int SpellNr = 0; + SpellNr < NARRAY(Slot->SpellList); + SpellNr += 1){ + if(Slot->SpellList[SpellNr] != 0){ + if(!FirstSpell){ + Script.writeText(","); + } + Script.writeNumber(SpellNr); + FirstSpell = false; + } + } + Script.writeText("}"); + Script.writeLn(); + + bool FirstQuest = true; + Script.writeText("QuestValues = {"); + for(int QuestNr = 0; + QuestNr < NARRAY(Slot->QuestValues); + QuestNr += 1){ + if(Slot->QuestValues[QuestNr] != 0){ + if(!FirstQuest){ + Script.writeText(","); + } + Script.writeText("("); + Script.writeNumber(QuestNr); + Script.writeText(","); + Script.writeNumber(Slot->QuestValues[QuestNr]); + Script.writeText(")"); + FirstQuest = false; + } + } + Script.writeText("}"); + Script.writeLn(); + + bool FirstMurder = true; + int Now = (int)time(NULL); + Script.writeText("Murders = {"); + for(int i = 0; i < NARRAY(Slot->MurderTimestamps); i += 1){ + // NOTE(fusion): Save murder timestamps for up to a month. + if((Now - Slot->MurderTimestamps[i]) < (30 * 24 * 60 * 60)){ + if(FirstMurder){ + Script.writeText(","); + } + Script.writeNumber(Slot->MurderTimestamps[i]); + FirstMurder = false; + } + } + Script.writeText("}"); + Script.writeLn(); + Script.writeLn(); + + bool FirstPosition = true; + Script.writeText("Inventory = {"); + if(Slot->Inventory != NULL){ + TReadBuffer Buffer(Slot->Inventory, Slot->InventorySize); + while(true){ + int Position = (int)Buffer.readByte(); + if(Position == 0xFF){ + break; + } + + if(FirstPosition){ + Script.writeText(","); + Script.writeLn(); + Script.writeText(" "); + } + Script.writeNumber(Position); + Script.writeText(" Content="); + SaveObjects(&Buffer, &Script); + FirstPosition = false; + } + } + Script.writeText("}"); + Script.writeLn(); + Script.writeLn(); + + bool FirstDepot = true; + Script.writeText("Depots = {"); + for(int DepotNr = 0; + DepotNr < NARRAY(Slot->Depot); + DepotNr += 1){ + if(Slot->Depot[DepotNr] != NULL){ + TReadBuffer Buffer(Slot->Depot[DepotNr], Slot->DepotSize[DepotNr]); + if(FirstDepot){ + Script.writeText(","); + Script.writeLn(); + Script.writeText(" "); + } + Script.writeNumber(DepotNr); + Script.writeText(" Content="); + SaveObjects(&Buffer, &Script); + FirstDepot = false; + } + } + Script.writeText("}"); + Script.writeLn(); + Script.close(); + + }catch(const char *str){ + error("SavePlayerData: Kann Gegenstände des Spielers %u nicht schreiben.\n", Slot->CharacterID); + error("# Fehler: %s\n", str); + unlink(FileName); + } +} + +void UnlinkPlayerData(uint32 CharacterID){ + char FileName[4096]; + PlayerDataPath(FileName, sizeof(FileName), CharacterID); + unlink(FileName); +} + // Player Pool // ============================================================================= void SavePlayerPoolSlot(TPlayerData *Slot){ diff --git a/src/main.cc b/src/main.cc index 43137bc..92e7e73 100644 --- a/src/main.cc +++ b/src/main.cc @@ -227,7 +227,7 @@ static void InitAll(void){ InitCommunication(); InitStrings(); InitWriter(); - //InitReader(); + InitReader(); InitObjects(); InitMap(); InitInfo(); @@ -244,8 +244,6 @@ static void InitAll(void){ } static void ExitAll(void){ - // TODO(fusion): Probably missing some inlined empty `Exit*` functions here. - EndGame(); ExitTime(); ExitCr(); @@ -255,7 +253,7 @@ static void ExitAll(void){ ExitHouses(); ExitMap(SaveMapOn); ExitObjects(); - //ExitReader(); + ExitReader(); ExitWriter(); ExitStrings(); ExitCommunication(); diff --git a/src/operate.hh b/src/operate.hh index 6d55416..ca7062d 100644 --- a/src/operate.hh +++ b/src/operate.hh @@ -37,6 +37,20 @@ enum : int { CHANNEL_LAST = 0xFFFF, }; +#if 0 +// TODO(fusion): Use the original channel enum instead of the one above? +enum CHANNEL: int { + GUILD_CHANNEL = 0, + GAMEMASTER_CHANNEL = 1, + TUTOR_CHANNEL = 2, + REQUEST_QUEUE = 3, + GAME_CHANNEL = 4, + TRADE_CHANNEL = 5, + REALLIFE_CHANNEL = 6, + HELP_CHANNEL = 7, +}; +#endif + struct TChannel { TChannel(void); -- cgit v1.2.3