diff options
| -rw-r--r-- | TODO.md | 1 | ||||
| -rw-r--r-- | reference/enums.hh | 10 | ||||
| -rw-r--r-- | reference/game.c | 735 | ||||
| -rw-r--r-- | src/cr.hh | 2 | ||||
| -rw-r--r-- | src/crplayer.cc | 506 | ||||
| -rw-r--r-- | src/main.cc | 6 | ||||
| -rw-r--r-- | src/operate.hh | 14 |
7 files changed, 523 insertions, 751 deletions
@@ -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
//==============================================================================
@@ -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); |
