From bdfcbb2f0edee2679bfe588df55e9f99bd837510 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Mon, 23 Jun 2025 06:34:16 -0300 Subject: `receiving.cc` --- Makefile | 6 +- TODO.md | 5 + reference/game.c | 3032 -------------------------------------------------- src/common.hh | 1 + src/communication.cc | 4 +- src/connections.hh | 13 +- src/cr.hh | 5 + src/info.cc | 6 +- src/operate.cc | 4 +- src/receiving.cc | 1818 ++++++++++++++++++++++++++++++ src/sending.cc | 31 +- src/stubs.hh | 4 +- 12 files changed, 1879 insertions(+), 3050 deletions(-) create mode 100644 src/receiving.cc diff --git a/Makefile b/Makefile index 357ae64..9294314 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ endif HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/communication.hh $(SRCDIR)/config.hh $(SRCDIR)/connections.hh $(SRCDIR)/containers.hh $(SRCDIR)/cr.hh $(SRCDIR)/crypto.hh $(SRCDIR)/enums.hh $(SRCDIR)/info.hh $(SRCDIR)/magic.hh $(SRCDIR)/map.hh $(SRCDIR)/moveuse.hh $(SRCDIR)/objects.hh $(SRCDIR)/operate.hh $(SRCDIR)/query.hh $(SRCDIR)/script.hh $(SRCDIR)/stubs.hh $(SRCDIR)/threads.hh -$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/communication.obj $(BUILDDIR)/config.obj $(BUILDDIR)/connections.obj $(BUILDDIR)/cract.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/crmain.obj $(BUILDDIR)/crplayer.obj $(BUILDDIR)/crskill.obj $(BUILDDIR)/crypto.obj $(BUILDDIR)/info.obj $(BUILDDIR)/magic.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/moveuse.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/operate.obj $(BUILDDIR)/query.obj $(BUILDDIR)/script.obj $(BUILDDIR)/sending.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/strings.obj $(BUILDDIR)/threads.obj $(BUILDDIR)/time.obj $(BUILDDIR)/utils.obj +$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/communication.obj $(BUILDDIR)/config.obj $(BUILDDIR)/connections.obj $(BUILDDIR)/cract.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/crmain.obj $(BUILDDIR)/crplayer.obj $(BUILDDIR)/crskill.obj $(BUILDDIR)/crypto.obj $(BUILDDIR)/info.obj $(BUILDDIR)/magic.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/moveuse.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/operate.obj $(BUILDDIR)/query.obj $(BUILDDIR)/receiving.obj $(BUILDDIR)/script.obj $(BUILDDIR)/sending.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/strings.obj $(BUILDDIR)/threads.obj $(BUILDDIR)/time.obj $(BUILDDIR)/utils.obj @echo $(CC) $(CFLAGS) $(LFLAGS) -o $@ $^ $(BUILDDIR)/communication.obj: $(SRCDIR)/communication.cc $(HEADERS) @@ -86,6 +86,10 @@ $(BUILDDIR)/query.obj: $(SRCDIR)/query.cc $(HEADERS) @mkdir -p $(@D) $(CC) -c $(CFLAGS) -o $@ $< +$(BUILDDIR)/receiving.obj: $(SRCDIR)/receiving.cc $(HEADERS) + @mkdir -p $(@D) + $(CC) -c $(CFLAGS) -o $@ $< + $(BUILDDIR)/script.obj: $(SRCDIR)/script.cc $(HEADERS) @mkdir -p $(@D) $(CC) -c $(CFLAGS) -o $@ $< diff --git a/TODO.md b/TODO.md index 19e483f..c389567 100644 --- a/TODO.md +++ b/TODO.md @@ -8,6 +8,11 @@ - WRITER.CC - DBFUNCS.CC +- Include `x == 0xFFFF` inside `CheckVisibility`? +- The map container uses type id zero but it seems to also be used as a "no type" + id which makes me want to add some `isNone()`, `isNull()`, `isVoid()` check to + `ObjectType` to be used as an alias when pertinent. + ## Stack allocations Any functions that use `alloca` or some other form of dynamic stack allocations will cause decompiled functions to be an absolute mess. It usually shows up in the decompiled code as both a size computation like `-(VAR + CONST & 0xfffffff0)`, followed by some assignment. It doesn't make total sense without looking at the disassembly. I've encountered ~30 such computations and expect the functions containing them to be amongt the most challenging/annoying to be properly decompiled. diff --git a/reference/game.c b/reference/game.c index 723efb5..06d70d8 100644 --- a/reference/game.c +++ b/reference/game.c @@ -26790,3038 +26790,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority return; } - - -bool CommandAllowed(TConnection *Connection,ushort Command) - -{ - CONNECTIONSTATE CVar1; - - if (Connection == (TConnection *)0x0) { - error("CommandAllowed: Connection ist NULL.\n"); - } - else { - CVar1 = Connection->State; - if (CVar1 == CONNECTION_GAME) { - return 1 < (ushort)(Command - 10); - } - if ((3 < (int)CVar1) && ((int)CVar1 < 7)) { - if ((Command != 0xe6) && (((Command != 0xe8 && (Command != 0x1e)) && (Command != 0x14))) - ) { - return false; - } - return true; - } - error(&DAT_08109f80,CVar1,(uint)Command); - } - return false; -} - - - -// WARNING: Unknown calling convention -- yet parameter storage is locked - -bool CheckSpecialCoordinates(void) - -{ - bool bVar1; - int in_stack_00000008; - int in_stack_0000000c; - int in_stack_00000010; - char in_stack_00000014; - - if (in_stack_00000008 == 0xffff) { - bVar1 = in_stack_00000014 != '\0'; - if (in_stack_0000000c != 0) { - if ((in_stack_0000000c - 0xbU < 0x35) || (0x4f < in_stack_0000000c)) { - print(); - bVar1 = false; - } - else { - bVar1 = true; - } - } - } - else { - bVar1 = IsOnMap(in_stack_00000008,in_stack_0000000c,in_stack_00000010); - } - return bVar1; -} - - - -// WARNING: Variable defined which should be unmapped: posz - -bool CheckVisibility(int Command,TConnection *Connection,int x,int y,int z) - -{ - bool bVar1; - int local_1c; - int posx; - int posy; - int posz; - - if (Connection == (TConnection *)0x0) { - error("CheckVisibility: Connection ist NULL.\n"); - } - else { - bVar1 = TConnection::IsVisible(Connection,x,y,z); - if (bVar1) { - return true; - } - TConnection::GetPosition(Connection,&local_1c,&posx,&posy); - print(); - } - return false; -} - - - -bool CheckObjectType(int Command,int TypeID) - -{ - bool bVar1; - - bVar1 = ObjectTypeExists(TypeID); - if (!bVar1) { - print(); - } - return bVar1; -} - - - -ObjectType GetObjectType(ushort TypeID) - -{ - bool bVar1; - uint TypeID_00; - undefined2 in_stack_00000006; - ushort in_stack_00000008; - - TypeID_00 = (uint)in_stack_00000008; - bVar1 = ObjectTypeExists(TypeID_00); - if (!bVar1) { - print(); - TypeID_00 = 0; - } - ObjectType::setTypeID(_TypeID,TypeID_00); - return (ObjectType)(int)_TypeID; -} - - - -void CGoDirection(TConnection *Connection,int dx,int dy) - -{ - bool bVar1; - RESULT r; - TPlayer *this; - TPlayer *pl; - int local_48; - int x; - int y; - int z; - TToDoEntry TD; - - if (Connection == (TConnection *)0x0) { - error("CGoDirection: Connection ist NULL.\n"); - } - else { - TConnection::GetPosition(Connection,&local_48,&x,&y); - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - // try { // try from 080d6a74 to 080d6abb has its CatchHandler @ 080d6ae0 - bVar1 = TCreature::ToDoClear(&this->super_TCreature); - if (bVar1) { - SendSnapback(Connection); - } - z = 1; - TD.field_1.Go.x = dy + x; - TD.Code = dx + local_48; - TD.field_1.Go.y = y; - TCreature::ToDoAdd(&this->super_TCreature,(TToDoEntry *)&z); - TCreature::ToDoStart(&this->super_TCreature); - } - } - return; -} - - - -void CGoPath(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - RESULT r; - uint uVar2; - TPlayer *this; - uint uVar3; - int Steps; - int local_50; - int i; - TPlayer *pl; - int x; - int y; - int z; - TToDoEntry TD; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080d6c37 to 080d6c3b has its CatchHandler @ 080d6c86 - error("CGoPath: Connection ist NULL.\n"); - } - else { - // try { // try from 080d6b42 to 080d6b6c has its CatchHandler @ 080d6c86 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - TConnection::GetPosition(Connection,(int *)&pl,&x,&y); - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - // try { // try from 080d6b77 to 080d6c27 has its CatchHandler @ 080d6c3e - bVar1 = TCreature::ToDoClear(&this->super_TCreature); - if (bVar1) { - SendSnapback(Connection); - } - local_50 = 0; - if ((uVar2 & 0xff) != 0) { - do { - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - switch(uVar3 & 0xff) { - default: - goto switchD_080d6ba0_caseD_0; - case 1: - pl = (TPlayer *)((int)&(pl->super_TCreature)._vptr_TCreature + 1); - goto LAB_080d6baa; - case 2: - pl = (TPlayer *)((int)&(pl->super_TCreature)._vptr_TCreature + 1); - break; - case 3: - break; - case 4: - pl = (TPlayer *)((int)pl[-1].AddresseesTimes + 0x4f); - break; - case 5: - pl = (TPlayer *)((int)pl[-1].AddresseesTimes + 0x4f); - goto LAB_080d6baa; - case 6: - pl = (TPlayer *)((int)pl[-1].AddresseesTimes + 0x4f); - case 7: - goto switchD_080d6ba0_caseD_7; - case 8: - pl = (TPlayer *)((int)&(pl->super_TCreature)._vptr_TCreature + 1); - goto switchD_080d6ba0_caseD_7; - } - x = x + -1; -LAB_080d6baa: - z = 1; - TD.Code = (ToDoType)pl; - TD.field_1.Go.x = x; - TD.field_1.Go.y = y; - TCreature::ToDoAdd(&this->super_TCreature,(TToDoEntry *)&z); -switchD_080d6ba0_caseD_0: - local_50 = local_50 + 1; - } while (local_50 < (int)(uVar2 & 0xff)); - } - TCreature::ToDoStart(&this->super_TCreature); - } - } - return; -switchD_080d6ba0_caseD_7: - x = x + 1; - goto LAB_080d6baa; -} - - - -void CStop(TConnection *Connection) - -{ - TPlayer *this; - - if (Connection == (TConnection *)0x0) { - error("CGoStop: Connection ist NULL.\n"); - return; - } - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - TCreature::ToDoStop(&this->super_TCreature); - return; - } - return; -} - - - -void CLookAtPoint(TConnection *Connection,TReadBuffer *Buffer) - -{ - ulong CreatureID_00; - bool bVar1; - TPlayer *pl; - uint uVar2; - uint uVar3; - uint uVar4; - TPlayer *pTVar5; - ObjectType *Type; - ObjectType *z; - int x; - ulong CreatureID; - int y; - int posx; - int posy; - int posz; - Object local_2c; - Object Obj; - - if (Connection == (TConnection *)0x0) { - error("CLookAtPoint: Connection ist NULL.\n"); - } - else { - // try { // try from 080d6d05 to 080d6df2 has its CatchHandler @ 080d6ee6 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - z = (ObjectType *)(uVar4 & 0xff); - bVar1 = CheckSpecialCoordinates(); - if (bVar1) { - if ((uVar2 == 0xffff) || - (bVar1 = TConnection::IsVisible(Connection,uVar2,uVar3 & 0xffff,(int)z), bVar1)) { - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 != (TPlayer *)0x0) { - CreatureID_00 = (pTVar5->super_TCreature).ID; - ObjectType::setTypeID((ObjectType *)&posz,0); - Type = (ObjectType *)0xffffffff; - if (uVar2 == 0xffff) { - Type = z; - } - GetObject((ulong)&local_2c,CreatureID_00,uVar2,uVar3 & 0xffff,(int)z,Type); - bVar1 = Object::exists(&local_2c); - if (bVar1) { - posz = local_2c.ObjectID; - // try { // try from 080d6e20 to 080d6e24 has its CatchHandler @ 080d6ea1 - Look(CreatureID_00,(Object *)&posz); - } - } - } - else { - // try { // try from 080d6e3f to 080d6e9b has its CatchHandler @ 080d6ee6 - TConnection::GetPosition(Connection,&y,&posx,&posy); - print(); - } - } - } - return; -} - - - -// WARNING: Variable defined which should be unmapped: posz - -void CRefreshField(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - uint uVar2; - uint uVar3; - TConnection *Connection_00; - int x_00; - int x; - int y; - int posx; - int posy; - int posz; - - if (Connection == (TConnection *)0x0) { - error("CRefreshField: Connection ist NULL.\n"); - } - else { - // try { // try from 080d6f22 to 080d700e has its CatchHandler @ 080d7014 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - Connection_00 = (TConnection *)(uVar3 & 0xffff); - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - bVar1 = IsOnMap(uVar2,(int)Connection_00,uVar3 & 0xff); - if (bVar1) { - bVar1 = TConnection::IsVisible(Connection,uVar2,(int)Connection_00,uVar3 & 0xff); - if (bVar1) { - SendFieldData(Connection_00,x_00,(int)Connection,uVar2); - } - else { - TConnection::GetPosition(Connection,&y,&posx,&posy); - print(); - } - } - } - return; -} - - - -void CTalk(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - int GamemasterID; - uint uVar2; - TPlayer *this; - char *pcVar3; - ulong uVar4; - TConnection *this_00; - TPlayer *pTVar5; - TCreature *pTVar6; - int iVar7; - uint uVar8; - int Mode; - TPlayer *pl; - int Channel; - char Text [256]; - char Addressee [30]; - - if (Connection == (TConnection *)0x0) { - error("CTalk: Connection ist NULL.\n"); - return; - } - // try { // try from 080d7055 to 080d713e has its CatchHandler @ 080d76f6 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar2 = uVar2 & 0xff; - if ((((((7 < uVar2 - 1) && (uVar2 != 0xb)) && (uVar2 != 0xf)) && - ((uVar2 != 10 && (uVar2 != 0xe)))) && (uVar2 != 9)) && (uVar2 != 0xd)) { -LAB_080d708d: - print(); - return; - } - Text[0xfc] = '\0'; - pl = (TPlayer *)0x0; - if ((((uVar2 == 4) || (uVar2 == 7)) || ((uVar2 == 0xb || (uVar2 == 0xf)))) && - ((*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,Text + 0xfc,0x1e), - Text[0xfc] == '\0')) goto LAB_080d7126; - if (((uVar2 == 5) || (uVar2 == 10)) || (uVar2 == 0xe)) { - uVar8 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - pl = (TPlayer *)(uVar8 & 0xffff); - iVar7 = GetNumberOfChannels(); - if (iVar7 <= (int)pl) goto LAB_080d708d; - sprintf(Text + 0xfc,"%d",pl); - } - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,&Channel,0x100); - if (((char)Channel == '\0') || - (this = TConnection::GetPlayer(Connection), this == (TPlayer *)0x0)) goto LAB_080d7126; - pcVar3 = strchr((char *)&Channel,10); - if (pcVar3 != (char *)0x0) { - error("CTalk: %s verwendet Newlines (%d,%s)\n",(this->super_TCreature).Name,uVar2,&Channel); - return; - } - if ((uVar2 == 7) && - (bVar1 = CheckRight((this->super_TCreature).ID,READ_GAMEMASTER_CHANNEL), !bVar1)) { - uVar2 = 4; - } - if ((uVar2 == 9) && - (bVar1 = CheckRight((this->super_TCreature).ID,GAMEMASTER_BROADCAST), !bVar1)) { - uVar2 = 1; - } - if ((uVar2 == 10) && - (bVar1 = CheckRight((this->super_TCreature).ID,GAMEMASTER_BROADCAST), !bVar1)) { - uVar2 = 5; - } - if ((uVar2 == 0xb) && - (bVar1 = CheckRight((this->super_TCreature).ID,GAMEMASTER_BROADCAST), !bVar1)) { - uVar2 = 4; - } - if ((uVar2 == 0xd) && - (bVar1 = CheckRight((this->super_TCreature).ID,ANONYMOUS_BROADCAST), !bVar1)) { - uVar2 = 1; - } - if ((uVar2 == 0xe) && - (bVar1 = CheckRight((this->super_TCreature).ID,ANONYMOUS_BROADCAST), !bVar1)) { - uVar2 = 5; - } - if ((uVar2 == 0xf) && - (bVar1 = CheckRight((this->super_TCreature).ID,ANONYMOUS_BROADCAST), !bVar1)) { - uVar2 = 4; - } - if ((uVar2 == 3) && - (iVar7 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[0]), iVar7 < 2)) { - pcVar3 = "You may not yell as long as you are on level 1."; - goto LAB_080d731f; - } - if (uVar2 == 5) { - iVar7 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[0]); - if (iVar7 < 2) { - pcVar3 = "You may not speak into channels as long as you are on level 1."; - goto LAB_080d731f; - } -LAB_080d7444: - if (pl == (TPlayer *)0x3) { -LAB_080d7126: - print(); - return; - } - } - else if ((uVar2 == 10) || (uVar2 == 0xe)) goto LAB_080d7444; - if ((((uVar2 == 5) || (uVar2 == 10)) || (uVar2 == 0xe)) && - (bVar1 = ChannelSubscribed((int)pl,(this->super_TCreature).ID), !bVar1)) { - Text[0xfc] = '\0'; - uVar2 = 1; - } - if (((uVar2 == 5) && (pl == (TPlayer *)0x7)) && - (bVar1 = CheckRight((this->super_TCreature).ID,HIGHLIGHT_HELP_CHANNEL), bVar1)) { - this->TutorActivities = this->TutorActivities + 1; - print(); - uVar2 = 0xc; - } - if (uVar2 == 8) { - if (this->Request == 0) { - return; - } - if (this->RequestProcessingGamemaster == 0) { - pcVar3 = "Please wait until your request is answered."; - goto LAB_080d731f; - } - pTVar6 = GetCreature(this->RequestProcessingGamemaster); - if (pTVar6 == (TCreature *)0x0) { - SendCloseRequest(Connection); - this->Request = 0; - return; - } - strcpy(Text + 0xfc,pTVar6->Name); - } - if (uVar2 != 6) { - // try { // try from 080d7226 to 080d7238 has its CatchHandler @ 080d76a6 - TCreature::ToDoTalk(&this->super_TCreature); - TCreature::ToDoStart(&this->super_TCreature); - return; - } - if (this->Request == 0) { - if ((char)Channel == '\0') { - return; - } - // try { // try from 080d7268 to 080d76a0 has its CatchHandler @ 080d76f6 - uVar4 = AddDynamicString((char *)&Channel); - this->Request = uVar4; - this->RequestTimestamp = RoundNr; - this->RequestProcessingGamemaster = 0; - this_00 = GetFirstConnection(); - if (this_00 == (TConnection *)0x0) { - return; - } - do { - if (((this_00->State - CONNECTION_LOGIN < 4) && - (pTVar5 = TConnection::GetPlayer(this_00), pTVar5 != (TPlayer *)0x0)) && - (bVar1 = ChannelSubscribed(3,(pTVar5->super_TCreature).ID), bVar1)) { - SendTalk(this_00,0,(this->super_TCreature).Name,6,(char *)&Channel,0); - } - this_00 = GetNextConnection(); - } while (this_00 != (TConnection *)0x0); - return; - } - pcVar3 = "You have already submitted a request. Please wait until it is answered."; -LAB_080d731f: - SendMessage(Connection,0x17,pcVar3); - return; -} - - - -void CGetChannels(TConnection *Connection) - -{ - if (Connection != (TConnection *)0x0) { - SendChannels(Connection); - return; - } - error("CGetChannels: Connection ist NULL.\n"); - return; -} - - - -void CJoinChannel(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - TPlayer *pl; - uint uVar2; - int iVar3; - TPlayer *pTVar4; - int Channel; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080d77c7 to 080d77cb has its CatchHandler @ 080d7816 - error("CJoinChannel: ist NULL.\n"); - } - else { - // try { // try from 080d774b to 080d776b has its CatchHandler @ 080d7816 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - iVar3 = GetNumberOfChannels(); - if ((int)uVar2 < iVar3) { - pTVar4 = TConnection::GetPlayer(Connection); - if (pTVar4 != (TPlayer *)0x0) { - // try { // try from 080d777d to 080d77b6 has its CatchHandler @ 080d77ce - bVar1 = JoinChannel(uVar2,(pTVar4->super_TCreature).ID); - if (uVar2 == 3) { - SendOpenRequestQueue(Connection); - SendExistingRequests(Connection); - } - else if (bVar1) { - SendOpenOwnChannel(Connection,uVar2); - } - else { - SendOpenChannel(Connection,uVar2); - } - } - } - } - return; -} - - - -void CLeaveChannel(TConnection *Connection,TReadBuffer *Buffer) - -{ - TPlayer *pl; - uint uVar1; - int iVar2; - TPlayer *pTVar3; - int Channel; - - if (Connection == (TConnection *)0x0) { - error("CLeaveChannel: Connection ist NULL.\n"); - } - else { - // try { // try from 080d784b to 080d789b has its CatchHandler @ 080d78a0 - uVar1 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - iVar2 = GetNumberOfChannels(); - if ((int)(uVar1 & 0xffff) < iVar2) { - pTVar3 = TConnection::GetPlayer(Connection); - if (pTVar3 != (TPlayer *)0x0) { - LeaveChannel(uVar1 & 0xffff,(pTVar3->super_TCreature).ID,true); - } - } - } - return; -} - - - -void CPrivateChannel(TConnection *Connection,TReadBuffer *Buffer) - -{ - ulong uVar1; - TPlayer *pTVar2; - char *Name_00; - ulong OppID; - char local_3c [4]; - char Name [30]; - - if (Connection == (TConnection *)0x0) { - error("CPrivateChannel: Connection ist NULL.\n"); - } - else { - // try { // try from 080d78f1 to 080d7972 has its CatchHandler @ 080d7975 - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,local_3c,0x1e); - if (local_3c[0] != '\0') { - uVar1 = GetCharacterID(local_3c); - if (uVar1 == 0) { - SendResult(Connection,PLAYERNOTEXISTING); - } - else { - pTVar2 = TConnection::GetPlayer(Connection); - if (uVar1 == (pTVar2->super_TCreature).ID) { - SendMessage(Connection,0x17, - "You cannot set up a private message channel with yourself."); - } - else { - Name_00 = GetCharacterName(local_3c); - SendPrivateChannel(Connection,Name_00); - } - } - } - } - return; -} - - - -void CProcessRequest(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - TPlayer *pTVar2; - int iVar3; - TPlayer *pl; - char *Text; - TPlayer *local_40; - TPlayer *Opp; - char Name [30]; - - if (Connection == (TConnection *)0x0) { - error("CProcessRequest: Connection ist NULL.\n"); - } - else { - // try { // try from 080d79b0 to 080d7a9d has its CatchHandler @ 080d7aa3 - pTVar2 = TConnection::GetPlayer(Connection); - if (((pTVar2 != (TPlayer *)0x0) && - (bVar1 = ChannelAvailable(3,(pTVar2->super_TCreature).ID), bVar1)) && - ((*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,&Opp,0x1e), (char)Opp != '\0' - )) { - iVar3 = IdentifyPlayer((char *)&Opp,true,true,&local_40); - if (iVar3 == 0) { - if ((local_40->Request != 0) && (local_40->RequestProcessingGamemaster == 0)) { - local_40->RequestProcessingGamemaster = (pTVar2->super_TCreature).ID; - DeleteGamemasterRequest((local_40->super_TCreature).Name); - return; - } - Text = "Request has already been processed."; - } - else { - Text = "Player is not online any more."; - } - SendMessage(Connection,0x17,Text); - SendFinishRequest(Connection,"Name"); - } - } - return; -} - - - -void CRemoveRequest(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - TPlayer *pTVar2; - int iVar3; - TPlayer *pl; - TPlayer *local_40; - TPlayer *Opp; - char Name [30]; - - if (Connection == (TConnection *)0x0) { - error("CRemoveRequest: Connection ist NULL.\n"); - } - else { - // try { // try from 080d7ae0 to 080d7bdc has its CatchHandler @ 080d7be2 - pTVar2 = TConnection::GetPlayer(Connection); - if (((pTVar2 != (TPlayer *)0x0) && - (bVar1 = ChannelAvailable(3,(pTVar2->super_TCreature).ID), bVar1)) && - ((*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,&Opp,0x1e), (char)Opp != '\0' - )) { - iVar3 = IdentifyPlayer((char *)&Opp,true,true,&local_40); - if (iVar3 == 0) { - if (local_40->Request != 0) { - if (local_40->RequestProcessingGamemaster == 0) { - DeleteGamemasterRequest((local_40->super_TCreature).Name); - } - else if (local_40->RequestProcessingGamemaster != (pTVar2->super_TCreature).ID) - { - return; - } - SendCloseRequest((local_40->super_TCreature).Connection); - local_40->Request = 0; - } - } - else { - SendMessage(Connection,0x17,"Player is not online any more."); - SendFinishRequest(Connection,"Name"); - } - } - } - return; -} - - - -void CCancelRequest(TConnection *Connection) - -{ - bool bVar1; - TPlayer *pTVar2; - TPlayer *pTVar3; - TPlayer *pl; - - if (Connection != (TConnection *)0x0) { - pTVar2 = TConnection::GetPlayer(Connection); - if (pTVar2 != (TPlayer *)0x0) { - bVar1 = ChannelAvailable(3,(pTVar2->super_TCreature).ID); - if ((bVar1) && (pTVar2->Request != 0)) { - if (pTVar2->RequestProcessingGamemaster == 0) { - DeleteGamemasterRequest((pTVar2->super_TCreature).Name); - } - else { - pTVar3 = GetPlayer(pTVar2->RequestProcessingGamemaster); - if (pTVar3 != (TPlayer *)0x0) { - SendFinishRequest((pTVar3->super_TCreature).Connection, - (pTVar2->super_TCreature).Name); - } - } - pTVar2->Request = 0; - } - } - return; - } - error("CCancelRequest: Connection ist NULL.\n"); - return; -} - - - -void CRotate(TConnection *Connection,int Direction) - -{ - RESULT r; - TPlayer *this; - TPlayer *pl; - - if (Connection != (TConnection *)0x0) { - if ((uint)Direction < 4) { - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - // try { // try from 080d7cf5 to 080d7d01 has its CatchHandler @ 080d7d20 - TCreature::ToDoRotate(&this->super_TCreature,Direction); - TCreature::ToDoStart(&this->super_TCreature); - } - } - return; - } - error("CRotate: Connection ist NULL.\n"); - return; -} - - - -void CBugReport(TConnection *Connection,TReadBuffer *Buffer) - -{ - uint *puVar1; - char cVar2; - int iVar3; - char *pcVar4; - time_t *ptVar5; - size_t sVar6; - uint *puVar7; - uint *puVar8; - uint uVar9; - uint uVar10; - int LineStart; - bool bVar11; - int iVar12; - int iVar13; - int iVar14; - int iVar15; - int iVar16; - size_t local_48c; - int LastSpace; - int i; - int local_47c; - int posx; - int posy; - int posz; - time_t Time; - char Line [80]; - char Text [1024]; - - if (Connection == (TConnection *)0x0) { - error("CBugReport: Connection ist NULL.\n"); - return; - } - puVar1 = (uint *)(Line + 0x4c); - // try { // try from 080d7d91 to 080d811b has its CatchHandler @ 080d8121 - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,puVar1,0x400); - while( true ) { - puVar8 = puVar1; - if (Line[0x4c] == '\0') { - return; - } - do { - puVar7 = puVar8; - uVar9 = *puVar7 + 0xfefefeff & ~*puVar7; - uVar10 = uVar9 & 0x80808080; - puVar8 = puVar7 + 1; - } while (uVar10 == 0); - bVar11 = (uVar9 & 0x8080) == 0; - if (bVar11) { - uVar10 = uVar10 >> 0x10; - } - if (bVar11) { - puVar8 = (uint *)((int)puVar7 + 6); - } - iVar3 = isprint((int)*(char *)((int)puVar8 + - (int)(Line + (-(int)puVar1 - - (uint)CARRY1((byte)uVar10,(byte)uVar10)) + 0x48)) - ); - puVar8 = puVar1; - if (iVar3 != 0) break; - do { - puVar7 = puVar8; - uVar9 = *puVar7 + 0xfefefeff & ~*puVar7; - uVar10 = uVar9 & 0x80808080; - puVar8 = puVar7 + 1; - } while (uVar10 == 0); - bVar11 = (uVar9 & 0x8080) == 0; - if (bVar11) { - uVar10 = uVar10 >> 0x10; - } - if (bVar11) { - puVar8 = (uint *)((int)puVar7 + 6); - } - *(char *)((int)puVar8 + - (int)(Line + (-(int)puVar1 - (uint)CARRY1((byte)uVar10,(byte)uVar10)) + 0x48)) = - '\0'; - } - if (Line[0x4c] == '\0') { - return; - } - time(&posz); - TConnection::GetPosition(Connection,&local_47c,&posx,&posy); - pcVar4 = ctime(&posz); - iVar13 = Connection->TerminalVersion; - iVar12 = Connection->TerminalType; - ptVar5 = (time_t *)TConnection::GetName(Connection); - Log("bugreport","%s - %d/%d - [%d,%d,%d] - %s",ptVar5,iVar12,iVar13,local_47c,posx,posy,pcVar4); - iVar3 = 0; - iVar14 = local_47c; - iVar15 = posx; - iVar16 = posy; -LAB_080d7f12: - do { - if (Line[iVar3 + 0x4c] == '\0') { - Log("bugreport", - "---------------------------------------------------------------------------\n", - ptVar5,iVar12,iVar13,iVar14,iVar15,iVar16,pcVar4); - SendMessage(Connection,0x15,"Comment sent."); - return; - } - local_48c = 0xffffffff; - LastSpace = 0; - while (cVar2 = Line[LastSpace + iVar3 + -0x1c + 0x68], cVar2 != '\0') { - if (0x4a < LastSpace) { - if (local_48c == 0xffffffff) { - strncpy((char *)&Time,(char *)(iVar3 + (int)puVar1),0x4a); - ptVar5 = &Time; - Line[0x46] = '-'; - Line[0x47] = '\0'; - Log("bugreport","%s\n",ptVar5,iVar12,iVar13,iVar14,iVar15,iVar16,pcVar4); - iVar3 = iVar3 + 0x4a; - } - else { - strncpy((char *)&Time,(char *)(iVar3 + (int)puVar1),local_48c); - Line[local_48c - 4] = '\0'; - ptVar5 = &Time; - Log("bugreport","%s\n",ptVar5); - if (Line[local_48c + iVar3 + -0x1c + 0x68] == ' ') { - iVar3 = iVar3 + 1; - } - iVar3 = iVar3 + local_48c; - } - goto LAB_080d7f12; - } - if (cVar2 == '\n') { - strncpy((char *)&Time,(char *)(iVar3 + (int)puVar1),LastSpace); - ptVar5 = &Time; - Line[LastSpace + -4] = '\0'; - Log("bugreport","%s\n",ptVar5); - iVar3 = LastSpace + 1 + iVar3; - goto LAB_080d7f12; - } - bVar11 = isSpace((int)cVar2); - sVar6 = LastSpace; - if (!bVar11) { - sVar6 = local_48c; - } - LastSpace = LastSpace + 1; - local_48c = sVar6; - } - ptVar5 = (time_t *)(iVar3 + (int)puVar1); - Log("bugreport","%s\n",ptVar5,iVar12,iVar13,iVar14,iVar15,iVar16,pcVar4); - iVar3 = iVar3 + LastSpace; - } while( true ); -} - - - -void CErrorFileEntry(TConnection *Connection,TReadBuffer *Buffer) - -{ - char cVar1; - int iVar2; - bool bVar3; - char *pcVar4; - char *pcVar5; - int iVar6; - time_t *__s; - size_t __n; - int LastSpace; - size_t __n_00; - time_t *ptVar7; - int local_b0c; - int posx; - int posy; - int posz; - time_t Time; - char Line [80]; - char Comment [513]; - time_t local_89c; - char Stack [2049]; - time_t local_8c; - char Date [27]; - undefined1 local_6c [4]; - char Title [65]; - - if (Connection == (TConnection *)0x0) { - error("CErrorFileEntry: Connection ist NULL.\n"); - } - else { - // try { // try from 080d8174 to 080d851e has its CatchHandler @ 080d8521 - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,local_6c,0x41); - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,&local_8c,0x1b); - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,&local_89c,0x801); - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,Line + 0x4c,0x201); - if (((char)local_89c != '\0') || (Line[0x4c] != '\0')) { - time(&posz); - TConnection::GetPosition(Connection,&local_b0c,&posx,&posy); - pcVar4 = ctime(&posz); - iVar6 = Connection->TerminalVersion; - iVar2 = Connection->TerminalType; - pcVar5 = TConnection::GetName(Connection); - Log("client-error","%s - %d/%d - [%d,%d,%d] - %s",pcVar5,iVar2,iVar6,local_b0c,posx,posy - ,pcVar4); - Log("client-error","%s\n",local_6c); - ptVar7 = &local_8c; - Log("client-error","%s\n",ptVar7); - Log("client-error","\n"); - __s = &local_89c; - while( true ) { - pcVar4 = strchr((char *)__s,10); - if (pcVar4 == (char *)0x0) break; - *pcVar4 = '\0'; - if ((char)*__s != '\0') { - Log("client-error","%s\n",__s); - ptVar7 = __s; - } - __s = (time_t *)(pcVar4 + 1); - } - if ((char)*__s != '\0') { - Log("client-error","%s\n",__s); - ptVar7 = __s; - } - if (((char)local_89c != '\0') && (Line[0x4c] != '\0')) { - Log("client-error","\n",ptVar7); - } - iVar6 = 0; -LAB_080d8335: - if (Line[iVar6 + 0x4c] != '\0') { - __n = 0; - __n_00 = 0xffffffff; - while (cVar1 = Line[__n + iVar6 + -0x1c + 0x68], cVar1 != '\0') { - if (0x4a < (int)__n) { - if (__n_00 == 0xffffffff) { - ptVar7 = &Time; - strncpy((char *)&Time,Line + iVar6 + 0x4c,0x4a); - Line[0x46] = '-'; - Line[0x47] = '\0'; - Log("client-error","%s\n",ptVar7); - iVar6 = iVar6 + 0x4a; - } - else { - ptVar7 = &Time; - strncpy((char *)&Time,Line + iVar6 + 0x4c,__n_00); - Line[__n_00 - 4] = '\0'; - Log("client-error","%s\n",ptVar7); - if (Line[__n_00 + iVar6 + -0x1c + 0x68] == ' ') { - iVar6 = iVar6 + 1; - } - iVar6 = iVar6 + __n_00; - } - goto LAB_080d8335; - } - if (cVar1 == '\n') { - strncpy((char *)&Time,Line + iVar6 + 0x4c,__n); - ptVar7 = &Time; - Line[__n - 4] = '\0'; - Log("client-error","%s\n",ptVar7); - iVar6 = __n + 1 + iVar6; - goto LAB_080d8335; - } - bVar3 = isSpace((int)cVar1); - if (bVar3) { - __n_00 = __n; - } - __n = __n + 1; - } - ptVar7 = (time_t *)(Line + iVar6 + 0x4c); - Log("client-error","%s\n",ptVar7); - iVar6 = iVar6 + __n; - goto LAB_080d8335; - } - Log("client-error", - "---------------------------------------------------------------------------\n", - ptVar7); - } - } - return; -} - - - -void CMoveObject(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - RESULT r; - uint uVar2; - uint uVar3; - uint uVar4; - uint uVar5; - int iVar6; - uint uVar7; - uint uVar8; - TPlayer *this; - int sx; - uint uVar9; - uint uVar10; - uint uVar11; - undefined4 uVar12; - TPlayer *pl; - uchar Count; - int zz; - int zy; - int zx; - uchar RNum; - int sz; - int sy; - int posx; - int posy; - int posz; - int posx_1; - int posy_1; - int posz_1; - ObjectType local_2c; - ObjectType Type; - - if (Connection == (TConnection *)0x0) { - error("CMoveObject: Connection ist NULL.\n"); - return; - } - // try { // try from 080d8565 to 080d870d has its CatchHandler @ 080d88c6 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - GetObjectType((ushort)&local_2c); - iVar6 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer,uVar5); - zx._3_1_ = (uchar)iVar6; - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - uVar7 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar7 = uVar7 & 0xffff; - uVar8 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar8 = uVar8 & 0xff; - iVar6 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - if (uVar2 != 0xffff) { - zx._3_1_ = '\x01'; - } - bVar1 = CheckSpecialCoordinates(); - if (!bVar1) { - return; - } - if ((uVar2 != 0xffff) && - (bVar1 = TConnection::IsVisible(Connection,uVar2,uVar3 & 0xffff,uVar4 & 0xff), !bVar1)) { - TConnection::GetPosition(Connection,&posz,&posx_1,&posy_1); - print(); - return; - } - uVar12 = 1; - uVar9 = uVar5; - uVar10 = uVar7; - uVar11 = uVar8; - bVar1 = CheckSpecialCoordinates(); - if (!bVar1) { - return; - } - if (uVar5 == 0xffff) goto LAB_080d86c1; - if (Connection == (TConnection *)0x0) { - error("CheckVisibility: Connection ist NULL.\n",uVar9,uVar10,uVar11,uVar12); -LAB_080d87dd: - bVar1 = false; - } - else { - bVar1 = TConnection::IsVisible(Connection,uVar5,uVar7,uVar8); - if (!bVar1) { - // try { // try from 080d8792 to 080d886b has its CatchHandler @ 080d88c6 - TConnection::GetPosition(Connection,&sy,&posx,&posy); - print(); - goto LAB_080d87dd; - } - bVar1 = true; - } - if (!bVar1) { - return; - } -LAB_080d86c1: - ObjectType::setTypeID((ObjectType *)&posz_1,0); - if ((local_2c.TypeID != posz_1) && - (((bVar1 = ObjectType::getFlag(&local_2c,CUMULATIVE), !bVar1 || ((uchar)iVar6 != '\0')) && - (this = TConnection::GetPlayer(Connection), this != (TPlayer *)0x0)))) { - // try { // try from 080d871f to 080d8774 has its CatchHandler @ 080d8871 - ObjectType::setTypeID((ObjectType *)&posz_1,local_2c.TypeID); - TCreature::ToDoMove(&this->super_TCreature,uVar2,uVar3 & 0xffff,uVar4 & 0xff, - (ObjectType *)&posz_1,zx._3_1_,uVar5,uVar7,uVar8,(uchar)iVar6); - TCreature::ToDoStart(&this->super_TCreature); - } - return; -} - - - -void CTradeObject(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - RESULT r; - uint uVar2; - uint uVar3; - uint uVar4; - uint uVar5; - int iVar6; - ulong TradePartner_00; - TPlayer *this; - ulong TradePartner; - TPlayer *pl; - uchar RNum; - int z; - int y; - int x; - int posx; - int posy; - int posz; - int local_2c; - ObjectType Type; - - if (Connection == (TConnection *)0x0) { - error("CTradeObject: Connection ist NULL.\n"); - } - else { - // try { // try from 080d8905 to 080d89fc has its CatchHandler @ 080d8b26 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - GetObjectType((ushort)&local_2c); - iVar6 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer,uVar5); - pl._3_1_ = (uchar)iVar6; - TradePartner_00 = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - if (uVar2 != 0xffff) { - pl._3_1_ = '\x01'; - } - bVar1 = CheckSpecialCoordinates(); - if (bVar1) { - if ((uVar2 == 0xffff) || - (bVar1 = TConnection::IsVisible(Connection,uVar2,uVar3 & 0xffff,uVar4 & 0xff), bVar1) - ) { - ObjectType::setTypeID((ObjectType *)&posz,0); - if ((local_2c != posz) && - (this = TConnection::GetPlayer(Connection), this != (TPlayer *)0x0)) { - // try { // try from 080d8a0e to 080d8a4d has its CatchHandler @ 080d8ad1 - ObjectType::setTypeID((ObjectType *)&posz,local_2c); - TCreature::ToDoTrade - (&this->super_TCreature,uVar2,uVar3 & 0xffff,uVar4 & 0xff, - (ObjectType *)&posz,pl._3_1_,TradePartner_00); - TCreature::ToDoStart(&this->super_TCreature); - } - } - else { - // try { // try from 080d8a68 to 080d8acb has its CatchHandler @ 080d8b26 - TConnection::GetPosition(Connection,&x,&posx,&posy); - print(); - } - } - } - return; -} - - - -void CInspectTrade(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - RESULT r; - uint uVar2; - TPlayer *pTVar3; - int Side; - TPlayer *pl; - Object local_2c; - Object Obj; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080d8bf7 to 080d8bfb has its CatchHandler @ 080d8c40 - error("CInspectTrade: Connection ist NULL.\n"); - } - else { - // try { // try from 080d8b62 to 080d8bb0 has its CatchHandler @ 080d8c40 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - pTVar3 = TConnection::GetPlayer(Connection); - if (pTVar3 != (TPlayer *)0x0) { - TPlayer::InspectTrade((TPlayer *)&local_2c,SUB41(pTVar3,0),(uint)((uVar2 & 0xff) == 0)); - bVar1 = Object::exists(&local_2c); - if (bVar1) { - pl = (TPlayer *)local_2c.ObjectID; - // try { // try from 080d8be6 to 080d8bea has its CatchHandler @ 080d8bfe - Look((pTVar3->super_TCreature).ID,(Object *)&pl); - } - } - } - return; -} - - - -void CAcceptTrade(TConnection *Connection) - -{ - TPlayer *this; - - if (Connection == (TConnection *)0x0) { - error("CAcceptTrade: Connection ist NULL.\n"); - return; - } - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - TPlayer::AcceptTrade(this); - return; - } - return; -} - - - -void CRejectTrade(TConnection *Connection) - -{ - TPlayer *this; - - if (Connection == (TConnection *)0x0) { - error("CRejectTrade: Connection ist NULL.\n"); - return; - } - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - TPlayer::RejectTrade(this); - return; - } - return; -} - - - -void CUseObject(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - uint uVar2; - uint uVar3; - uint uVar4; - uint uVar5; - int iVar6; - int iVar7; - TPlayer *this; - int x; - TPlayer *pl; - uchar Dummy; - uchar RNum; - int z; - int y; - int posx; - int posy; - int posz; - ObjectType local_3c [4]; - ObjectType local_2c; - ObjectType Type; - - if (Connection == (TConnection *)0x0) { - error("CUseObject: Connection ist NULL.\n"); - } - else { - // try { // try from 080d8cf5 to 080d8e0a has its CatchHandler @ 080d8f86 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - GetObjectType((ushort)&local_2c); - iVar6 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer,uVar5); - iVar7 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - bVar1 = CheckSpecialCoordinates(); - if (bVar1) { - if ((uVar2 == 0xffff) || - (bVar1 = TConnection::IsVisible(Connection,uVar2,uVar3 & 0xffff,uVar4 & 0xff), bVar1) - ) { - ObjectType::setTypeID(local_3c,0); - if ((((local_2c.TypeID != local_3c[0].TypeID) && - (bVar1 = ObjectType::getFlag(&local_2c,MULTIUSE), !bVar1)) && - ((bVar1 = ObjectType::getFlag(&local_2c,CONTAINER), !bVar1 || - ((byte)iVar7 < 0x10)))) && - (this = TConnection::GetPlayer(Connection), this != (TPlayer *)0x0)) { - // try { // try from 080d8e1d to 080d8eae has its CatchHandler @ 080d8f31 - TCreature::ToDoWait(&this->super_TCreature,100); - ObjectType::setTypeID(local_3c,0); - ObjectType::setTypeID((ObjectType *)&posz,local_2c.TypeID); - TCreature::ToDoUse(&this->super_TCreature,'\x01',uVar2,uVar3 & 0xffff, - uVar4 & 0xff,(ObjectType *)&posz,(uchar)iVar6,(byte)iVar7,0,0 - ,0,local_3c,'\0'); - TCreature::ToDoStart(&this->super_TCreature); - } - } - else { - // try { // try from 080d8ecc to 080d8f2b has its CatchHandler @ 080d8f86 - TConnection::GetPosition(Connection,&y,&posx,&posy); - print(); - } - } - } - return; -} - - - -void CUseTwoObjects(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - uint uVar2; - uint uVar3; - uint uVar4; - uint uVar5; - int iVar6; - uint uVar7; - uint uVar8; - uint uVar9; - int iVar10; - TPlayer *this; - int x1; - uint uVar11; - uint uVar12; - undefined4 uVar13; - TPlayer *pl; - uchar RNum2; - int z2; - int y2; - int x2; - uchar RNum1; - int z1; - int y1; - int posx; - int posy; - int posz; - int posx_1; - int posy_1; - int posz_1; - ObjectType local_4c [4]; - int local_3c; - ObjectType Type2; - ObjectType local_2c; - ObjectType Type1; - - if (Connection == (TConnection *)0x0) { - error("CUseTwoObjects: Connection ist NULL.\n"); - return; - } - // try { // try from 080d8fc5 to 080d91a8 has its CatchHandler @ 080d93c0 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - GetObjectType((ushort)&local_2c); - iVar6 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer,uVar5); - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - uVar7 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar7 = uVar7 & 0xffff; - uVar8 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar8 = uVar8 & 0xff; - uVar9 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar9 = uVar9 & 0xffff; - GetObjectType((ushort)&local_3c); - iVar10 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer,uVar9); - bVar1 = CheckSpecialCoordinates(); - if (!bVar1) { - return; - } - if ((uVar2 != 0xffff) && - (bVar1 = TConnection::IsVisible(Connection,uVar2,uVar3 & 0xffff,uVar4 & 0xff), !bVar1)) { - TConnection::GetPosition(Connection,&posz,&posx_1,&posy_1); - print(); - return; - } - ObjectType::setTypeID(local_4c,0); - if (local_2c.TypeID == local_4c[0].TypeID) { - return; - } - bVar1 = ObjectType::getFlag(&local_2c,MULTIUSE); - if (!bVar1) { - return; - } - uVar13 = 0; - uVar9 = uVar5; - uVar11 = uVar7; - uVar12 = uVar8; - bVar1 = CheckSpecialCoordinates(); - if (!bVar1) { - return; - } - if (uVar5 == 0xffff) goto LAB_080d9182; - if (Connection == (TConnection *)0x0) { - error("CheckVisibility: Connection ist NULL.\n",uVar9,uVar11,uVar12,uVar13); -LAB_080d92d0: - bVar1 = false; - } - else { - bVar1 = TConnection::IsVisible(Connection,uVar5,uVar7,uVar8); - if (!bVar1) { - // try { // try from 080d927f to 080d935b has its CatchHandler @ 080d93c0 - TConnection::GetPosition(Connection,&y1,&posx,&posy); - print(); - goto LAB_080d92d0; - } - bVar1 = true; - } - if (!bVar1) { - return; - } -LAB_080d9182: - ObjectType::setTypeID(local_4c,0); - if ((local_3c != local_4c[0].TypeID) && - (this = TConnection::GetPlayer(Connection), this != (TPlayer *)0x0)) { - // try { // try from 080d91c2 to 080d9261 has its CatchHandler @ 080d9361 - TCreature::ToDoWait(&this->super_TCreature,100); - ObjectType::setTypeID(local_4c,local_3c); - ObjectType::setTypeID((ObjectType *)&posz_1,local_2c.TypeID); - TCreature::ToDoUse(&this->super_TCreature,'\x02',uVar2,uVar3 & 0xffff,uVar4 & 0xff, - (ObjectType *)&posz_1,(uchar)iVar6,'\0',uVar5,uVar7,uVar8,local_4c, - (uchar)iVar10); - TCreature::ToDoStart(&this->super_TCreature); - } - return; -} - - - -void CUseOnCreature(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - uint uVar2; - uint uVar3; - uint uVar4; - uint uVar5; - uint uVar6; - ulong id; - TCreature *pTVar7; - TPlayer *this; - undefined4 uVar8; - RESULT r; - uint uVar9; - undefined4 uVar10; - TPlayer *pl; - uchar RNum; - int z; - int y; - int x; - int posx; - int posy; - int posz; - int posx_1; - int posy_1; - int posz_1; - Object local_5c [4]; - Object local_4c; - Object Obj2; - Object local_3c; - Object Obj1; - ulong local_2c; - ObjectType Type; - - if (Connection == (TConnection *)0x0) { - error("CUseOnCreature: Connection ist NULL.\n"); - return; - } - // try { // try from 080d93f5 to 080d9655 has its CatchHandler @ 080d9826 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar3 = uVar3 & 0xffff; - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar4 = uVar4 & 0xff; - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - GetObjectType((ushort)&local_2c); - uVar6 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer,uVar5); - id = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - uVar10 = 0; - uVar5 = uVar3; - uVar9 = uVar4; - bVar1 = CheckSpecialCoordinates(); - if (!bVar1) { - return; - } - if ((uVar2 != 0xffff) && - (uVar5 = uVar3, uVar9 = uVar4, bVar1 = TConnection::IsVisible(Connection,uVar2,uVar3,uVar4), - !bVar1)) { - TConnection::GetPosition(Connection,&posz,&posx_1,&posy_1); - print(); - return; - } - uVar8 = 0; - ObjectType::setTypeID((ObjectType *)&local_3c,0); - if (local_2c == local_3c.ObjectID) { - return; - } - pTVar7 = GetCreature(id); - if (pTVar7 == (TCreature *)0x0) { - return; - } - if (Connection == (TConnection *)0x0) { - error("CheckVisibility: Connection ist NULL.\n",uVar8,uVar5,uVar9,uVar10); -LAB_080d9726: - bVar1 = false; - } - else { - bVar1 = TConnection::IsVisible(Connection,pTVar7->posx,pTVar7->posy,pTVar7->posz); - if (!bVar1) { - // try { // try from 080d96d8 to 080d97be has its CatchHandler @ 080d9826 - TConnection::GetPosition(Connection,&x,&posx,&posy); - print(); - goto LAB_080d9726; - } - bVar1 = true; - } - if (!bVar1) { - return; - } - if (pTVar7->Type == PLAYER) { - return; - } - this = TConnection::GetPlayer(Connection); - if (this == (TPlayer *)0x0) { - return; - } - uVar5 = (this->super_TCreature).posx - pTVar7->posx; - if (0x7fffffff < uVar5) { - uVar5 = -uVar5; - } - if ((int)uVar5 < Connection->TerminalOffsetX) { - uVar5 = (this->super_TCreature).posy - pTVar7->posy; - if (0x7fffffff < uVar5) { - uVar5 = -uVar5; - } - if ((int)uVar5 < Connection->TerminalOffsetY) { - ObjectType::setTypeID((ObjectType *)&local_4c,local_2c); - GetObject((ulong)&local_3c,(this->super_TCreature).ID,uVar2,uVar3,uVar4, - (ObjectType *)(uVar6 & 0xff)); - local_4c.ObjectID = (pTVar7->CrObject).ObjectID; - bVar1 = Object::exists(&local_3c); - if ((bVar1) && (bVar1 = Object::exists(&local_4c), bVar1)) { - // try { // try from 080d9678 to 080d96ba has its CatchHandler @ 080d97c4 - TCreature::ToDoWait(&this->super_TCreature,100); - local_5c[0].ObjectID = local_4c.ObjectID; - posz_1 = local_3c.ObjectID; - TCreature::ToDoUse(&this->super_TCreature,'\x02',(Object *)&posz_1,local_5c); - TCreature::ToDoStart(&this->super_TCreature); - return; - } - r = NOTACCESSIBLE; - goto LAB_080d95cc; - } - } - r = OUTOFRANGE; -LAB_080d95cc: - SendResult(Connection,r); - return; -} - - - -void CTurnObject(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - uint uVar2; - uint uVar3; - uint uVar4; - uint uVar5; - int iVar6; - TPlayer *this; - TPlayer *pl; - int z; - int y; - int x; - int posx; - int posy; - int posz; - int local_2c; - ObjectType Type; - - if (Connection == (TConnection *)0x0) { - error("CTurnObject: Connection ist NULL.\n"); - } - else { - // try { // try from 080d9865 to 080d9944 has its CatchHandler @ 080d9a76 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar5 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar5 = uVar5 & 0xffff; - GetObjectType((ushort)&local_2c); - iVar6 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer,uVar5); - bVar1 = CheckSpecialCoordinates(); - if (bVar1) { - if ((uVar2 == 0xffff) || - (bVar1 = TConnection::IsVisible(Connection,uVar2,uVar3 & 0xffff,uVar4 & 0xff), bVar1) - ) { - ObjectType::setTypeID((ObjectType *)&posz,0); - if ((local_2c != posz) && - (this = TConnection::GetPlayer(Connection), this != (TPlayer *)0x0)) { - // try { // try from 080d9957 to 080d99a0 has its CatchHandler @ 080d9a21 - TCreature::ToDoWait(&this->super_TCreature,100); - ObjectType::setTypeID((ObjectType *)&posz,local_2c); - TCreature::ToDoTurn(&this->super_TCreature,uVar2,uVar3 & 0xffff,uVar4 & 0xff, - (ObjectType *)&posz,(uchar)iVar6); - TCreature::ToDoStart(&this->super_TCreature); - } - } - else { - // try { // try from 080d99bb to 080d9a1b has its CatchHandler @ 080d9a76 - TConnection::GetPosition(Connection,&x,&posx,&posy); - print(); - } - } - } - return; -} - - - -void CCloseContainer(TConnection *Connection,TReadBuffer *Buffer) - -{ - uint uVar1; - TPlayer *this; - TPlayer *pl; - int Window; - Object local_1c [4]; - - if (Connection == (TConnection *)0x0) { - error("CCloseContainer: Connection ist NULL.\n"); - } - else { - // try { // try from 080d9aab to 080d9b02 has its CatchHandler @ 080d9b05 - uVar1 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar1 = uVar1 & 0xff; - if (uVar1 < 0x10) { - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - local_1c[0].ObjectID = NONE.ObjectID; - TPlayer::SetOpenContainer(this,uVar1,local_1c); - SendCloseContainer(Connection,uVar1); - } - } - } - return; -} - - - -void CUpContainer(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - uint uVar2; - TPlayer *this; - int Window; - TPlayer *pl; - Object local_4c [4]; - _func_int_varargs **local_3c; - _func_int_varargs **local_2c; - Object Con; - - if (Connection == (TConnection *)0x0) { - error("CUpContainer: Connection ist NULL.\n"); - } - else { - // try { // try from 080d9b42 to 080d9c5b has its CatchHandler @ 080d9c61 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar2 = uVar2 & 0xff; - if ((uVar2 < 0x10) && (this = TConnection::GetPlayer(Connection), this != (TPlayer *)0x0)) { - TPlayer::GetOpenContainer((TPlayer *)&local_2c,(int)this); - local_3c = (_func_int_varargs **)NONE.ObjectID; - if (local_2c != (_func_int_varargs **)NONE.ObjectID) { - Object::getContainer(local_4c); - local_2c = (_func_int_varargs **)local_4c[0].ObjectID; - local_3c = (_func_int_varargs **)local_4c[0].ObjectID; - Object::getObjectType(local_4c); - if ((_func_int_varargs **)local_4c[0].ObjectID != (_func_int_varargs **)0x0) { - Object::getObjectType(local_4c); - bVar1 = false; - if ((0 < (int)local_4c[0].ObjectID) && ((int)local_4c[0].ObjectID < 0xb)) { - bVar1 = true; - } - if (!bVar1) { - local_4c[0].ObjectID = (ulong)local_2c; - TPlayer::SetOpenContainer(this,uVar2,local_4c); - SendContainer(Connection,uVar2); - return; - } - } - local_4c[0].ObjectID = NONE.ObjectID; - TPlayer::SetOpenContainer(this,uVar2,local_4c); - SendCloseContainer(Connection,uVar2); - } - } - } - return; -} - - - -void CRefreshContainer(TConnection *Connection,TReadBuffer *Buffer) - -{ - uint uVar1; - TPlayer *Window_00; - int Window; - _func_int_varargs **local_1c; - Object Con; - - if (Connection == (TConnection *)0x0) { - error("CRefreshContainer: Connection ist NULL.\n"); - } - else { - // try { // try from 080d9c9b to 080d9cfb has its CatchHandler @ 080d9d00 - uVar1 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - if ((uVar1 & 0xff) < 0x10) { - Window_00 = TConnection::GetPlayer(Connection); - if (Window_00 != (TPlayer *)0x0) { - TPlayer::GetOpenContainer((TPlayer *)&local_1c,(int)Window_00); - if (local_1c != (_func_int_varargs **)NONE.ObjectID) { - SendContainer(Connection,uVar1 & 0xff); - } - } - } - } - return; -} - - - -void CGetOutfit(TConnection *Connection) - -{ - bool bVar1; - TPlayer *pl; - TPlayer *pTVar2; - - if (Connection == (TConnection *)0x0) { - error("CGetOutfit: Connection ist NULL.\n"); - return; - } - pTVar2 = TConnection::GetPlayer(Connection); - if (pTVar2 != (TPlayer *)0x0) { - bVar1 = CheckRight((pTVar2->super_TCreature).ID,GAMEMASTER_OUTFIT); - if (!bVar1) { - SendOutfit(Connection); - return; - } - SendMessage(Connection,0x17,"You may not change your outfit."); - } - return; -} - - - -void CSetOutfit(TConnection *Connection,TReadBuffer *Buffer) - -{ - TPlayer *pTVar1; - uint uVar2; - int iVar3; - TOutfit *pTVar4; - int OutfitID; - TOutfit *pTVar5; - bool bVar6; - TPlayer *pl; - TOutfit NewOutfit; - undefined4 local_18; - uchar Colors [4]; - - if (Connection == (TConnection *)0x0) { - error("CSetOutfit: Connection ist NULL.\n"); - return; - } - // try { // try from 080d9dc0 to 080d9f8e has its CatchHandler @ 080d9f94 - pTVar1 = TConnection::GetPlayer(Connection); - if (pTVar1 == (TPlayer *)0x0) { - return; - } - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[2])(Buffer); - uVar2 = uVar2 & 0xffff; - (*(Buffer->super_TReadStream)._vptr_TReadStream[5])(Buffer,&local_18,4); - iVar3 = (pTVar1->super_TCreature).Sex; - if (iVar3 == 1) { - bVar6 = false; - if ((0x7f < uVar2) && (uVar2 < 0x87)) { - bVar6 = true; - } - if (bVar6) { - bVar6 = CheckRight((pTVar1->super_TCreature).ID,PREMIUM_ACCOUNT); - if (bVar6) { - iVar3 = (pTVar1->super_TCreature).Sex; - } - else { - if (0x83 < uVar2) goto LAB_080d9f0c; - iVar3 = (pTVar1->super_TCreature).Sex; - } - goto LAB_080d9e00; - } -LAB_080d9f0c: - print(); - } - else { -LAB_080d9e00: - if (iVar3 == 2) { - bVar6 = false; - if ((0x87 < uVar2) && (uVar2 < 0x8f)) { - bVar6 = true; - } - if ((!bVar6) || - ((bVar6 = CheckRight((pTVar1->super_TCreature).ID,PREMIUM_ACCOUNT), !bVar6 && - (0x8b < uVar2)))) goto LAB_080d9f0c; - } - if (((((byte)local_18 < 0x85) && (local_18._1_1_ < 0x85)) && (local_18._2_1_ < 0x85)) && - (local_18._3_1_ < 0x85)) { - iVar3 = 8; - pTVar4 = &(pTVar1->super_TCreature).OrgOutfit; - bVar6 = pTVar4 == (TOutfit *)0x0; - pTVar5 = &(pTVar1->super_TCreature).Outfit; - do { - if (iVar3 == 0) break; - iVar3 = iVar3 + -1; - bVar6 = (char)pTVar4->OutfitID == (char)pTVar5->OutfitID; - pTVar4 = (TOutfit *)((int)&pTVar4->OutfitID + 1); - pTVar5 = (TOutfit *)((int)&pTVar5->OutfitID + 1); - } while (bVar6); - if (bVar6) { - (pTVar1->super_TCreature).Outfit.OutfitID = uVar2; - *(undefined4 *)&(pTVar1->super_TCreature).Outfit.field_1.ObjectType = local_18; - AnnounceChangedCreature((pTVar1->super_TCreature).ID,3); - } - (pTVar1->super_TCreature).OrgOutfit.OutfitID = uVar2; - *(undefined4 *)&(pTVar1->super_TCreature).OrgOutfit.field_1.ObjectType = local_18; - } - else { - print(); - } - } - return; -} - - - -void CEditText(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - RESULT r; - ulong uVar2; - TPlayer *pTVar3; - TPlayer *pl; - uint uVar4; - uint uVar5; - uint *puVar6; - uint *puVar7; - RESULT r_00; - uint local_103c; - char Text [4096]; - Object local_2c; - Object Obj; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080da177 to 080da17b has its CatchHandler @ 080da1c6 - error("CEditText: Connection ist NULL.\n"); - return; - } - // try { // try from 080d9fd8 to 080da136 has its CatchHandler @ 080da1c6 - local_2c.ObjectID = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - bVar1 = Object::exists(&local_2c); - if (bVar1) { - Object::getObjectType((Object *)(Text + 0xffc)); - bVar1 = ObjectType::getFlag((ObjectType *)(Text + 0xffc),WRITE); - if (!bVar1) { - Object::getObjectType((Object *)(Text + 0xffc)); - bVar1 = ObjectType::getFlag((ObjectType *)(Text + 0xffc),WRITEONCE); - if ((!bVar1) || (uVar2 = Object::getAttribute(&local_2c,TEXTSTRING), uVar2 != 0)) - goto LAB_080da050; - } - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,&local_103c,0x1000); - puVar7 = &local_103c; - do { - puVar6 = puVar7; - uVar4 = *puVar6 + 0xfefefeff & ~*puVar6; - uVar5 = uVar4 & 0x80808080; - puVar7 = puVar6 + 1; - } while (uVar5 == 0); - bVar1 = (uVar4 & 0x8080) == 0; - if (bVar1) { - uVar5 = uVar5 >> 0x10; - } - if (bVar1) { - puVar7 = (uint *)((int)puVar6 + 6); - } - Object::getObjectType((Object *)(Text + 0xffc)); - bVar1 = ObjectType::getFlag((ObjectType *)(Text + 0xffc),WRITE); - Object::getObjectType((Object *)(Text + 0xffc)); - uVar2 = ObjectType::getAttribute((ObjectType *)(Text + 0xffc),!bVar1 + MAXLENGTH); - if ((int)puVar7 + ((-3 - (uint)CARRY1((byte)uVar5,(byte)uVar5)) - (int)&local_103c) < uVar2) - { - pTVar3 = TConnection::GetPlayer(Connection); - if (pTVar3 == (TPlayer *)0x0) { - return; - } - Text[0xffc] = (undefined1)local_2c.ObjectID; - Text[0xffd] = local_2c.ObjectID._1_1_; - Text[0xffe] = local_2c.ObjectID._2_1_; - Text[0xfff] = local_2c.ObjectID._3_1_; - // try { // try from 080da161 to 080da165 has its CatchHandler @ 080da181 - EditText((pTVar3->super_TCreature).ID,(Object *)(Text + 0xffc),(char *)&local_103c); - return; - } - r_00 = NOROOM; - } - else { -LAB_080da050: - r_00 = NOTACCESSIBLE; - } - SendResult(Connection,r_00); - return; -} - - - -void CEditList(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - RESULT r; - uint uVar2; - ulong uVar3; - TPlayer *pl; - uint uVar4; - ulong ID; - Object OStack_104c; - uchar Type; - ulong local_103c; - Object local_102c; - Object Door; - char local_101c [4]; - char Text [4096]; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080da3a7 to 080da3ab has its CatchHandler @ 080da3f6 - error("CEditList: Connection ist NULL.\n"); - } - else { - // try { // try from 080da205 to 080da241 has its CatchHandler @ 080da3f6 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,local_101c,0x1000); - local_102c.ObjectID = 0; - pl = TConnection::GetPlayer(Connection); - if (pl != (TPlayer *)0x0) { - uVar4 = uVar2 & 0xff; - if (uVar4 == 2) { - ChangeSubowners((ushort)uVar3,pl,local_101c); - } - else { - if (uVar4 < 3) { - if (uVar4 == 1) { - ChangeGuests((ushort)uVar3,pl,local_101c); - return; - } - } - else if (uVar4 == 3) { - OStack_104c.ObjectID = uVar3; - local_103c = uVar3; - local_102c.ObjectID = uVar3; - bVar1 = Object::exists(&local_102c); - if (bVar1) { - Object::getObjectType(&stack0xffffefb4); - bVar1 = ObjectType::getFlag((ObjectType *)&stack0xffffefb4,NAMEDOOR); - if (bVar1) { - Object::getObjectType(&stack0xffffefb4); - bVar1 = ObjectType::getFlag((ObjectType *)&stack0xffffefb4,TEXT); - if (bVar1) { - OStack_104c.ObjectID = local_102c.ObjectID; - ChangeNameDoor(&stack0xffffefb4,pl,local_101c); - return; - } - } - } - SendResult(Connection,NOTACCESSIBLE); - return; - } - // try { // try from 080da272 to 080da398 has its CatchHandler @ 080da3b1 - error("CEditList: Unbekannter Typ %d.\n",uVar2 & 0xff); - } - } - } - return; -} - - - -// WARNING: Variable defined which should be unmapped: ChaseMode - -void CSetTactics(TConnection *Connection,TReadBuffer *Buffer) - -{ - TCombat *this; - bool bVar1; - uint uVar2; - uint uVar3; - uint uVar4; - TPlayer *pTVar5; - TPlayer *pl; - int AttackMode; - int ChaseMode; - - if (Connection == (TConnection *)0x0) { - error("CSetTactics: Connection ist NULL.\n"); - } - else { - // try { // try from 080da432 to 080da51b has its CatchHandler @ 080da521 - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - bVar1 = false; - if (((uVar2 & 0xff) != 0) && ((uVar2 & 0xff) < 4)) { - bVar1 = true; - } - if (((bVar1) && ((uVar3 & 0xff) < 2)) && ((uVar4 & 0xff) < 2)) { - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 != (TPlayer *)0x0) { - this = &(pTVar5->super_TCreature).Combat; - TCombat::SetAttackMode(this,(uchar)uVar2); - TCombat::SetChaseMode(this,(uchar)uVar3); - TCombat::SetSecureMode(this,(uchar)uVar4); - } - } - else { - print(); - } - } - return; -} - - - -// WARNING: Variable defined which should be unmapped: pl - -void CAttack(TConnection *Connection,TReadBuffer *Buffer,bool Follow) - -{ - ulong CreatureID; - TPlayer *this; - ulong dfd; - TPlayer *pl; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080da5c7 to 080da5cb has its CatchHandler @ 080da620 - error("CAttack: Connection ist NULL.\n"); - } - else { - // try { // try from 080da560 to 080da573 has its CatchHandler @ 080da620 - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - dfd = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - // try { // try from 080da58a to 080da5a4 has its CatchHandler @ 080da5d0 - TCombat::SetAttackDest(&(this->super_TCreature).Combat,dfd,Follow); - TCreature::ToDoAttack(&this->super_TCreature); - TCreature::ToDoStart(&this->super_TCreature); - } - } - return; -} - - - -// WARNING: Variable defined which should be unmapped: posz - -void CInviteToParty(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - TCreature *guest; - TPlayer *pTVar2; - ulong id; - TCreature *pTVar3; - TPlayer *pl; - int local_1c; - int posx; - int posy; - int posz; - - if (Connection == (TConnection *)0x0) { - error("CInviteToParty: Connection ist NULL.\n"); - } - else { - // try { // try from 080da650 to 080da74b has its CatchHandler @ 080da751 - pTVar2 = TConnection::GetPlayer(Connection); - if (pTVar2 != (TPlayer *)0x0) { - id = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - pTVar3 = GetCreature(id); - if (pTVar3 != (TCreature *)0x0) { - bVar1 = TConnection::IsVisible(Connection,pTVar3->posx,pTVar3->posy,pTVar3->posz); - if (bVar1) { - InviteToParty((pTVar2->super_TCreature).ID,id); - } - else { - TConnection::GetPosition(Connection,&local_1c,&posx,&posy); - print(); - } - } - } - } - return; -} - - - -void CJoinParty(TConnection *Connection,TReadBuffer *Buffer) - -{ - TPlayer *pTVar1; - ulong Host; - TPlayer *pl; - - if (Connection == (TConnection *)0x0) { - error("CJoinParty: Connection ist NULL.\n"); - } - else { - // try { // try from 080da789 to 080da7c3 has its CatchHandler @ 080da7c6 - pTVar1 = TConnection::GetPlayer(Connection); - if (pTVar1 != (TPlayer *)0x0) { - Host = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - JoinParty((pTVar1->super_TCreature).ID,Host); - } - } - return; -} - - - -void CRevokeInvitation(TConnection *Connection,TReadBuffer *Buffer) - -{ - TPlayer *this; - ulong Guest; - ulong uVar1; - TPlayer *pl; - - if (Connection == (TConnection *)0x0) { - error("CRevokeInvitation: Connection ist NULL.\n"); - } - else { - // try { // try from 080da7f9 to 080da86b has its CatchHandler @ 080da870 - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - Guest = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - uVar1 = TPlayer::GetPartyLeader(this,false); - if (uVar1 == 0) { - print(); - } - else { - RevokeInvitation((this->super_TCreature).ID,Guest); - } - } - } - return; -} - - - -void CPassLeadership(TConnection *Connection,TReadBuffer *Buffer) - -{ - TPlayer *this; - ulong NewLeader; - ulong uVar1; - TPlayer *pl; - - if (Connection == (TConnection *)0x0) { - error("CPassLeadership: Connection ist NULL.\n"); - } - else { - // try { // try from 080da8a9 to 080da91b has its CatchHandler @ 080da920 - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - NewLeader = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - uVar1 = TPlayer::GetPartyLeader(this,false); - if (uVar1 == 0) { - print(); - } - else { - PassLeadership((this->super_TCreature).ID,NewLeader); - } - } - } - return; -} - - - -void CLeaveParty(TConnection *Connection) - -{ - TPlayer *this; - ulong uVar1; - TPlayer *pl; - - if (Connection != (TConnection *)0x0) { - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - uVar1 = TPlayer::GetPartyLeader(this,false); - if (uVar1 == 0) { - print(); - } - else { - LeaveParty((this->super_TCreature).ID,false); - } - } - return; - } - error("CLeaveParty: Connection ist NULL.\n"); - return; -} - - - -void COpenChannel(TConnection *Connection) - -{ - TPlayer *pl; - TPlayer *pTVar1; - - if (Connection != (TConnection *)0x0) { - pTVar1 = TConnection::GetPlayer(Connection); - if (pTVar1 != (TPlayer *)0x0) { - // try { // try from 080da9e8 to 080da9ec has its CatchHandler @ 080daa10 - OpenChannel((pTVar1->super_TCreature).ID); - } - return; - } - error("COpenChannel: Connection ist NULL.\n"); - return; -} - - - -void CInviteToChannel(TConnection *Connection,TReadBuffer *Buffer) - -{ - RESULT r; - TPlayer *pTVar1; - TPlayer *pl; - char local_3c [4]; - char PlayerName [30]; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080daadb to 080daadf has its CatchHandler @ 080dab20 - error("CInviteToChannel: Connection ist NULL.\n"); - } - else { - // try { // try from 080daa6c to 080daaa7 has its CatchHandler @ 080dab20 - pTVar1 = TConnection::GetPlayer(Connection); - if (pTVar1 != (TPlayer *)0x0) { - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,local_3c,0x1e); - if (local_3c[0] == '\0') { - print(); - } - else { - // try { // try from 080daacd to 080daad1 has its CatchHandler @ 080daae2 - InviteToChannel((pTVar1->super_TCreature).ID,local_3c); - } - } - } - return; -} - - - -void CExcludeFromChannel(TConnection *Connection,TReadBuffer *Buffer) - -{ - RESULT r; - TPlayer *pTVar1; - TPlayer *pl; - char local_3c [4]; - char PlayerName [30]; - - if (Connection == (TConnection *)0x0) { - // try { // try from 080dab97 to 080dab9b has its CatchHandler @ 080dabe0 - error("CExcludeFromChannel: Connection ist NULL.\n"); - } - else { - // try { // try from 080dab49 to 080dab6d has its CatchHandler @ 080dabe0 - pTVar1 = TConnection::GetPlayer(Connection); - if (pTVar1 != (TPlayer *)0x0) { - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,local_3c,0x1e); - // try { // try from 080dab7b to 080dab7f has its CatchHandler @ 080dab9e - ExcludeFromChannel((pTVar1->super_TCreature).ID,local_3c); - } - } - return; -} - - - -void CCancel(TConnection *Connection) - -{ - bool bVar1; - TPlayer *this; - TPlayer *pl; - - if (Connection == (TConnection *)0x0) { - error("CCancel: Connection ist NULL.\n"); - return; - } - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - // try { // try from 080dac22 to 080dac2e has its CatchHandler @ 080dac75 - TCombat::StopAttack(&(this->super_TCreature).Combat,0); - bVar1 = TCreature::ToDoClear(&this->super_TCreature); - if (bVar1) { - // try { // try from 080dac47 to 080dac4b has its CatchHandler @ 080dac75 - SendSnapback(Connection); - } - TCreature::ToDoYield(&this->super_TCreature); - return; - } - return; -} - - - -// WARNING: Variable defined which should be unmapped: Name - -void CAddBuddy(TConnection *Connection,TReadBuffer *Buffer) - -{ - TPlayer *pl; - TPlayer *this; - char local_2c [4]; - char Name [30]; - - if (Connection == (TConnection *)0x0) { - error("CAddBuddy: Connection ist NULL.\n"); - } - else { - // try { // try from 080dacba to 080dacfb has its CatchHandler @ 080dad00 - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,local_2c,0x1e); - if (local_2c[0] != '\0') { - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - TPlayer::AddBuddy(this,local_2c); - } - } - } - return; -} - - - -void CRemoveBuddy(TConnection *Connection,TReadBuffer *Buffer) - -{ - TPlayer *pl; - ulong CharacterID_00; - TPlayer *this; - ulong CharacterID; - - if (Connection == (TConnection *)0x0) { - error("CRemoveBuddy: Connection ist NULL.\n"); - } - else { - // try { // try from 080dad3b to 080dad6d has its CatchHandler @ 080dad70 - CharacterID_00 = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - this = TConnection::GetPlayer(Connection); - if (this != (TPlayer *)0x0) { - TPlayer::RemoveBuddy(this,CharacterID_00); - } - } - return; -} - - - -void CRuleViolation(TConnection *Connection,TReadBuffer *Buffer) - -{ - bool bVar1; - ulong CriminalID; - TPlayer *cr; - uint uVar2; - uint uVar3; - ulong StatementID_00; - int iVar4; - ulong uVar5; - TPlayer *Gamemaster; - bool IPBanishment; - char *pcVar6; - char *local_128; - char *IPAddress; - ulong StatementID; - int Action; - int Reason; - int NumberOfStatements; - vector<> *ReportedStatements; - TPlayer *Criminal; - char Comment [200]; - char local_3c [4]; - char Name [30]; - - if (Connection == (TConnection *)0x0) { - error("CRuleViolation: Connection ist NULL.\n"); - return; - } - // try { // try from 080dadb3 to 080db14e has its CatchHandler @ 080db154 - cr = TConnection::GetPlayer(Connection); - if (cr == (TPlayer *)0x0) { - return; - } - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,local_3c,0x1e); - Trim(local_3c); - uVar2 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar2 = uVar2 & 0xff; - uVar3 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - uVar3 = uVar3 & 0xff; - (*(Buffer->super_TReadStream)._vptr_TReadStream[4])(Buffer,&Criminal,200); - StatementID_00 = (*(Buffer->super_TReadStream)._vptr_TReadStream[3])(Buffer); - iVar4 = (*(Buffer->super_TReadStream)._vptr_TReadStream[1])(Buffer); - IPBanishment = (char)iVar4 != '\0'; - bVar1 = CheckBanishmentRight((cr->super_TCreature).ID,uVar2,uVar3); - if ((!bVar1) || - ((IPBanishment && (bVar1 = CheckRight((cr->super_TCreature).ID,IP_BANISHMENT), !bVar1)))) { - pcVar6 = "You have no authorization for this action."; - goto LAB_080daf27; - } - if ((char)Criminal == '\0') { - pcVar6 = "Please provide a comment for this report."; - goto LAB_080daf27; - } - if ((uVar3 == 6) && (StatementID_00 == 0)) { - pcVar6 = "Please provide a statement for this rule violation."; - goto LAB_080daf27; - } - local_128 = (char *)0x0; - ReportedStatements = (vector<> *)0x0; - bVar1 = CheckRight((cr->super_TCreature).ID,READ_GAMEMASTER_CHANNEL); - iVar4 = IdentifyPlayer(local_3c,false,!bVar1,(TPlayer **)&ReportedStatements); - if (iVar4 == 0) { - bVar1 = CheckRight(*(ulong *)(ReportedStatements[1].init.Text + 0xac),NO_BANISHMENT); - if (!bVar1) { - strcpy(local_3c,ReportedStatements[1].init.Text + 0xb8); - local_128 = ReportedStatements[2].init.Text + 0xf1; - goto LAB_080daf8c; - } - if (((uVar3 == 1) || (uVar3 == 3)) || (uVar3 == 5)) { - pcVar6 = "This name has already been approved."; - goto LAB_080daf27; - } - if (uVar3 != 6) { - pcVar6 = "You may not report a god or gamemaster."; - goto LAB_080daf27; - } - } - else { - uVar5 = GetCharacterID(local_3c); - if (uVar5 == 0) { - SendResult(Connection,PLAYERNOTEXISTING); - return; - } - pcVar6 = GetCharacterName(local_3c); - strcpy(local_3c,pcVar6); - if (IPBanishment) { - SendMessage(Connection,0x17,"Player is not online. No IP address was banished."); - IPBanishment = false; - } -LAB_080daf8c: - Reason = 0; - bVar1 = false; - NumberOfStatements = 0; - if ((0x1a < uVar2 + 0x12) && (uVar2 + 0x12 < 0x2e)) { - bVar1 = true; - } - if (((!bVar1) && (uVar2 != 0x1d)) || (StatementID_00 == 0)) { -LAB_080dafc4: - PunishmentOrder(&cr->super_TCreature,local_3c,local_128,uVar2,uVar3,(char *)&Criminal, - Reason,(vector<> *)NumberOfStatements,StatementID_00,IPBanishment); - return; - } - uVar5 = 0; - if (uVar3 != 6) { - uVar5 = (cr->super_TCreature).ID; - } - iVar4 = GetCommunicationContext - (uVar5,StatementID_00,&Reason,(vector<> **)&NumberOfStatements); - if (iVar4 == 1) { - pcVar6 = "Statement is unknown. Perhaps it is too old?"; - goto LAB_080daf27; - } - if (iVar4 != 2) goto LAB_080dafc4; - } - pcVar6 = "Statement has already been reported."; -LAB_080daf27: - SendMessage(Connection,0x17,pcVar6); - return; -} - - - -void CQuitGame(TConnection *Connection) - -{ - TPlayer *this; - int iVar1; - TPlayer *pl; - char *Text; - - this = TConnection::GetPlayer(Connection); - if (this == (TPlayer *)0x0) goto LAB_080db1b8; - iVar1 = TCreature::LogoutPossible(&this->super_TCreature); - if (iVar1 == 1) { - Text = "You may not logout during or immediately after a fight!"; -LAB_080db1e2: - SendMessage(Connection,0x17,Text); - return; - } - if (iVar1 < 2) { - if (iVar1 != 0) goto LAB_080db1a4; - } - else { - if (iVar1 == 2) { - Text = "You may not logout here!"; - goto LAB_080db1e2; - } -LAB_080db1a4: - error(&DAT_0810b2e0); - } - TCreature::ToDoClear(&this->super_TCreature); -LAB_080db1b8: - TConnection::Logout(Connection,0,true); - return; -} - - - -void ReceiveData(TConnection *Connection) - -{ - byte bVar1; - bool bVar2; - int Length; - int iVar3; - ulong uVar4; - TPlayer *pTVar5; - TPlayer *pl; - int Command; - uint uVar6; - char *pcVar7; - int dx; - undefined1 local_2c [4]; - TReadBuffer Buffer; - - if (Connection == (TConnection *)0x0) { - pcVar7 = "ReceiveData: Connection ist NULL.\n"; -LAB_080db8fa: - error(pcVar7); - return; - } - uVar6 = Connection->InDataSize; - if ((int)uVar6 < 1) { - pcVar7 = "ReceiveData: Keine Daten vorhanden.\n"; - goto LAB_080db8fa; - } - if (0x7fe < (int)uVar6) { - pcVar7 = &DAT_0810b360; -LAB_080db24a: - error(pcVar7,uVar6); - return; - } - TReadBuffer::TReadBuffer((TReadBuffer *)local_2c,Connection->InData + 2,uVar6); - // try { // try from 080db279 to 080db27d has its CatchHandler @ 080db910 - bVar1 = TReadBuffer::readByte((TReadBuffer *)local_2c); - uVar6 = (uint)bVar1; - if (Connection->State == CONNECTION_LOGIN) { - if (uVar6 == 0xb) { - bVar2 = TConnection::JoinGame(Connection,(TReadBuffer *)local_2c); - if (bVar2) { - return; - } - Log("game","Einloggen gescheitert.\n"); - SendResult(Connection,LOGINERROR); - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 == (TPlayer *)0x0) { - error("ReceiveData: Einloggen gescheitert und keine Kreatur bekannt.\n"); - } - else { - DecrementIsOnlineOrder((pTVar5->super_TCreature).ID); - } - TConnection::Disconnect(Connection); - return; - } - pcVar7 = "ReceiveData: Falsches Login-Kommando %d.\n"; - goto LAB_080db24a; - } - bVar2 = CommandAllowed(Connection,(ushort)bVar1); - if (!bVar2) { - return; - } - TConnection::ResetTimer(Connection,uVar6); - switch(uVar6) { - case 0x14: - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 != (TPlayer *)0x0) { - iVar3 = TCreature::LogoutPossible(&pTVar5->super_TCreature); - if (iVar3 == 1) { - pcVar7 = "You may not logout during or immediately after a fight!"; -LAB_080db32b: - SendMessage(Connection,0x17,pcVar7); - return; - } - if (iVar3 < 2) { - if (iVar3 != 0) goto LAB_080db2f2; - } - else { - if (iVar3 == 2) { - pcVar7 = "You may not logout here!"; - goto LAB_080db32b; - } -LAB_080db2f2: - error(&DAT_0810b2e0); - } - TCreature::ToDoClear(&pTVar5->super_TCreature); - } - TConnection::Logout(Connection,0,true); - break; - default: - // try { // try from 080db834 to 080db86b has its CatchHandler @ 080db982 - print(); - break; - case 0x1e: - break; - case 100: - // try { // try from 080db2c6 to 080db587 has its CatchHandler @ 080db982 - CGoPath(Connection,(TReadBuffer *)local_2c); - break; - case 0x65: - iVar3 = -1; - goto LAB_080db358; - case 0x66: - iVar3 = 0; - goto LAB_080db375; - case 0x67: - iVar3 = 1; -LAB_080db358: - dx = 0; - goto LAB_080db360; - case 0x68: - iVar3 = 0; - goto LAB_080db391; - case 0x69: - if (Connection != (TConnection *)0x0) { - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 == (TPlayer *)0x0) { - return; - } - TCreature::ToDoStop(&pTVar5->super_TCreature); - return; - } - pcVar7 = "CGoStop: Connection ist NULL.\n"; - goto LAB_080db3c3; - case 0x6a: - iVar3 = -1; - goto LAB_080db375; - case 0x6b: - iVar3 = 1; -LAB_080db375: - dx = 1; -LAB_080db360: - CGoDirection(Connection,dx,iVar3); - break; - case 0x6c: - iVar3 = 1; - goto LAB_080db391; - case 0x6d: - iVar3 = -1; -LAB_080db391: - dx = -1; - goto LAB_080db360; - case 0x6f: - iVar3 = 0; - goto LAB_080db3fd; - case 0x70: - iVar3 = 1; - goto LAB_080db3fd; - case 0x71: - iVar3 = 2; - goto LAB_080db3fd; - case 0x72: - iVar3 = 3; -LAB_080db3fd: - CRotate(Connection,iVar3); - break; - case 0x78: - CMoveObject(Connection,(TReadBuffer *)local_2c); - break; - case 0x7d: - CTradeObject(Connection,(TReadBuffer *)local_2c); - break; - case 0x7e: - CInspectTrade(Connection,(TReadBuffer *)local_2c); - break; - case 0x7f: - if (Connection != (TConnection *)0x0) { - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 == (TPlayer *)0x0) { - return; - } - TPlayer::AcceptTrade(pTVar5); - return; - } - pcVar7 = "CAcceptTrade: Connection ist NULL.\n"; - goto LAB_080db3c3; - case 0x80: - if (Connection != (TConnection *)0x0) { - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 == (TPlayer *)0x0) { - return; - } - TPlayer::RejectTrade(pTVar5); - return; - } - pcVar7 = "CRejectTrade: Connection ist NULL.\n"; - goto LAB_080db3c3; - case 0x82: - CUseObject(Connection,(TReadBuffer *)local_2c); - break; - case 0x83: - CUseTwoObjects(Connection,(TReadBuffer *)local_2c); - break; - case 0x84: - CUseOnCreature(Connection,(TReadBuffer *)local_2c); - break; - case 0x85: - CTurnObject(Connection,(TReadBuffer *)local_2c); - break; - case 0x87: - CCloseContainer(Connection,(TReadBuffer *)local_2c); - break; - case 0x88: - CUpContainer(Connection,(TReadBuffer *)local_2c); - break; - case 0x89: - CEditText(Connection,(TReadBuffer *)local_2c); - break; - case 0x8a: - CEditList(Connection,(TReadBuffer *)local_2c); - break; - case 0x8c: - CLookAtPoint(Connection,(TReadBuffer *)local_2c); - break; - case 0x96: - CTalk(Connection,(TReadBuffer *)local_2c); - break; - case 0x97: - if (Connection != (TConnection *)0x0) { - SendChannels(Connection); - return; - } - pcVar7 = "CGetChannels: Connection ist NULL.\n"; - goto LAB_080db3c3; - case 0x98: - CJoinChannel(Connection,(TReadBuffer *)local_2c); - break; - case 0x99: - if (Connection == (TConnection *)0x0) { - error("CLeaveChannel: Connection ist NULL.\n"); - } - else { - // try { // try from 080db597 to 080db5eb has its CatchHandler @ 080db946 - uVar6 = (**(_func_int_varargs **)((int)local_2c + 8))((TReadBuffer *)local_2c); - iVar3 = GetNumberOfChannels(); - if (((int)(uVar6 & 0xffff) < iVar3) && - (pTVar5 = TConnection::GetPlayer(Connection), pTVar5 != (TPlayer *)0x0)) { - LeaveChannel(uVar6 & 0xffff,(pTVar5->super_TCreature).ID,true); - } - } - break; - case 0x9a: - // try { // try from 080db5f8 to 080db670 has its CatchHandler @ 080db982 - CPrivateChannel(Connection,(TReadBuffer *)local_2c); - break; - case 0x9b: - CProcessRequest(Connection,(TReadBuffer *)local_2c); - break; - case 0x9c: - CRemoveRequest(Connection,(TReadBuffer *)local_2c); - break; - case 0x9d: - CCancelRequest(Connection); - break; - case 0xa0: - CSetTactics(Connection,(TReadBuffer *)local_2c); - break; - case 0xa1: - bVar2 = false; - goto LAB_080db64a; - case 0xa2: - bVar2 = true; -LAB_080db64a: - CAttack(Connection,(TReadBuffer *)local_2c,bVar2); - break; - case 0xa3: - CInviteToParty(Connection,(TReadBuffer *)local_2c); - break; - case 0xa4: - if (Connection == (TConnection *)0x0) { - error("CJoinParty: Connection ist NULL.\n"); - } - else { - // try { // try from 080db67d to 080db6bb has its CatchHandler @ 080db980 - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 != (TPlayer *)0x0) { - uVar4 = (**(_func_int_varargs **)((int)local_2c + 0xc))((TReadBuffer *)local_2c); - JoinParty((pTVar5->super_TCreature).ID,uVar4); - } - } - break; - case 0xa5: - // try { // try from 080db6c8 to 080db7d4 has its CatchHandler @ 080db982 - CRevokeInvitation(Connection,(TReadBuffer *)local_2c); - break; - case 0xa6: - CPassLeadership(Connection,(TReadBuffer *)local_2c); - break; - case 0xa7: - if (Connection != (TConnection *)0x0) { - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 == (TPlayer *)0x0) { - return; - } - uVar4 = TPlayer::GetPartyLeader(pTVar5,false); - if (uVar4 == 0) { - print(); - return; - } - LeaveParty((pTVar5->super_TCreature).ID,false); - return; - } - pcVar7 = "CLeaveParty: Connection ist NULL.\n"; -LAB_080db3c3: - error(pcVar7); - break; - case 0xaa: - COpenChannel(Connection); - break; - case 0xab: - CInviteToChannel(Connection,(TReadBuffer *)local_2c); - break; - case 0xac: - CExcludeFromChannel(Connection,(TReadBuffer *)local_2c); - break; - case 0xbe: - CCancel(Connection); - break; - case 0xc9: - CRefreshField(Connection,(TReadBuffer *)local_2c); - break; - case 0xca: - CRefreshContainer(Connection,(TReadBuffer *)local_2c); - break; - case 0xd2: - CGetOutfit(Connection); - break; - case 0xd3: - CSetOutfit(Connection,(TReadBuffer *)local_2c); - break; - case 0xdc: - CAddBuddy(Connection,(TReadBuffer *)local_2c); - break; - case 0xdd: - if (Connection == (TConnection *)0x0) { - error("CRemoveBuddy: Connection ist NULL.\n"); - } - else { - // try { // try from 080db7e4 to 080db81b has its CatchHandler @ 080db946 - uVar4 = (**(_func_int_varargs **)((int)local_2c + 0xc))((TReadBuffer *)local_2c); - pTVar5 = TConnection::GetPlayer(Connection); - if (pTVar5 != (TPlayer *)0x0) { - TPlayer::RemoveBuddy(pTVar5,uVar4); - } - } - break; - case 0xe6: - CBugReport(Connection,(TReadBuffer *)local_2c); - break; - case 0xe7: - CRuleViolation(Connection,(TReadBuffer *)local_2c); - break; - case 0xe8: - CErrorFileEntry(Connection,(TReadBuffer *)local_2c); - } - return; -} - - - -// WARNING: Unknown calling convention -- yet parameter storage is locked - -void ReceiveData(void) - -{ - TConnection *Connection_00; - pid_t __pid; - TConnection *Connection; - - Connection_00 = GetFirstConnection(); - while (Connection_00 != (TConnection *)0x0) { - if ((Connection_00->State - CONNECTION_LOGIN < 4) && (Connection_00->WaitingForACK != false) - ) { - ReceiveData(Connection_00); - Connection_00->WaitingForACK = false; - if (Connection_00->State - CONNECTION_LOGIN < 4) { - __pid = TConnection::GetPID(Connection_00); - kill(__pid,10); - } - } - Connection_00 = GetNextConnection(); - } - return; -} - - - // WARNING: Unknown calling convention -- yet parameter storage is locked void _GLOBAL__I__Z14CommandAllowedP11TConnectiont(void) diff --git a/src/common.hh b/src/common.hh index e0bfb81..8aef0fd 100644 --- a/src/common.hh +++ b/src/common.hh @@ -1,6 +1,7 @@ #ifndef TIBIA_COMMON_HH_ #define TIBIA_COMMON_HH_ 1 +#include #include #include #include diff --git a/src/communication.cc b/src/communication.cc index 71a05d3..799cd42 100644 --- a/src/communication.cc +++ b/src/communication.cc @@ -920,7 +920,7 @@ bool HandleLogin(TConnection *Connection){ TReadBuffer InputBuffer(Connection->InData, Connection->InDataSize); try{ uint8 Command = InputBuffer.readByte(); - if(Command != 10){ + if(Command != CL_CMD_LOGIN_REQUEST){ print(3, "Ungültiges Init-Kommando %d.\n", Command); return false; } @@ -1104,7 +1104,7 @@ bool HandleLogin(TConnection *Connection){ TWriteBuffer WriteBuffer(Connection->InData + 2, sizeof(Connection->InData) - 2); try{ - WriteBuffer.writeByte(11); + WriteBuffer.writeByte(CL_CMD_LOGIN); WriteBuffer.writeWord((int)TerminalType); WriteBuffer.writeWord((int)TerminalVersion); WriteBuffer.writeQuad(Slot->CharacterID); diff --git a/src/connections.hh b/src/connections.hh index 17cf7df..d4f0755 100644 --- a/src/connections.hh +++ b/src/connections.hh @@ -10,11 +10,11 @@ struct TConnection; struct TPlayer; enum ClientCommand: int { - CL_CMD_LOGIN = 10, - CL_CMD_LOGIN_TREATED = 11, + CL_CMD_LOGIN_REQUEST = 10, + CL_CMD_LOGIN = 11, CL_CMD_LOGOUT = 20, CL_CMD_PING = 30, - CL_CMD_GO = 100, + CL_CMD_GO_PATH = 100, CL_CMD_GO_NORTH = 101, CL_CMD_GO_EAST = 102, CL_CMD_GO_SOUTH = 103, @@ -121,7 +121,7 @@ enum ServerCommand: int { SV_CMD_CHANNELS = 171, SV_CMD_OPEN_CHANNEL = 172, SV_CMD_PRIVATE_CHANNEL = 173, - SV_CMD_OPEN_REQUEST = 174, + SV_CMD_OPEN_REQUEST_QUEUE = 174, SV_CMD_DELETE_REQUEST = 175, SV_CMD_FINISH_REQUEST = 176, SV_CMD_CLOSE_REQUEST = 177, @@ -288,7 +288,7 @@ void SendTalk(TConnection *Connection, uint32 StatementID, void SendChannels(TConnection *Connection); void SendOpenChannel(TConnection *Connection, int Channel); void SendPrivateChannel(TConnection *Connection, const char *Name); -void SendOpenRequest(TConnection *Connection); +void SendOpenRequestQueue(TConnection *Connection); void SendDeleteRequest(TConnection *Connection, const char *Name); void SendFinishRequest(TConnection *Connection, const char *Name); void SendCloseRequest(TConnection *Connection); @@ -300,11 +300,14 @@ void SendOutfit(TConnection *Connection); void SendBuddyData(TConnection *Connection, uint32 CharacterID, const char *Name, bool Online); void SendBuddyStatus(TConnection *Connection, uint32 CharacterID, bool Online); void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3); +void CreateGamemasterRequest(const char *Name, const char *Text); void DeleteGamemasterRequest(const char *Name); void InitSending(void); void ExitSending(void); // receiving.cc +void ReceiveData(TConnection *Connection); +void ReceiveData(void); void InitReceiving(void); void ExitReceiving(void); diff --git a/src/cr.hh b/src/cr.hh index a971b3b..f36f7bf 100644 --- a/src/cr.hh +++ b/src/cr.hh @@ -18,6 +18,11 @@ struct TOutfit{ uint8 Colors[4]; uint32 PackedData; }; + + constexpr bool operator==(const TOutfit &Other) const { + return this->OutfitID == Other.OutfitID + && this->PackedData == Other.PackedData; + } }; struct TSkillData { diff --git a/src/info.cc b/src/info.cc index 0461356..8f520cf 100644 --- a/src/info.cc +++ b/src/info.cc @@ -399,9 +399,7 @@ Object GetObject(uint32 CreatureID, int x, int y, int z, int RNum, ObjectType Ty error("GetObject: Ungültiger ContainerCode x=%d,y=%d,z=%d,RNum=%d,Type=%d.\n", x, y, z, RNum, Type.TypeID); } - }else if(RNum == -1){ - Obj = GetTopObject(x, y, z, false); - }else{ + }else if(RNum != -1){ Obj = GetFirstObject(x, y, z); while(Obj != NONE){ if(Obj.getObjectType().getDisguise() == Type){ @@ -409,6 +407,8 @@ Object GetObject(uint32 CreatureID, int x, int y, int z, int RNum, ObjectType Ty } Obj = Obj.getNextObject(); } + }else{ + Obj = GetTopObject(x, y, z, false); } // NOTE(fusion): `Type` can be a map container (TypeID = 0) as a wildcard for diff --git a/src/operate.cc b/src/operate.cc index e019d36..6fb7f20 100644 --- a/src/operate.cc +++ b/src/operate.cc @@ -2634,8 +2634,8 @@ void EditText(uint32 CreatureID, Object Obj, const char *Text){ int TextLength = (int)strlen(Text); int MaxLength = (ObjType.getFlag(WRITE) - ? ObjType.getAttribute(MAXLENGTH) - : ObjType.getAttribute(MAXLENGTHONCE)); + ? (int)ObjType.getAttribute(MAXLENGTH) + : (int)ObjType.getAttribute(MAXLENGTHONCE)); if(TextLength >= MaxLength){ throw TOOLONG; } diff --git a/src/receiving.cc b/src/receiving.cc new file mode 100644 index 0000000..1c6ee00 --- /dev/null +++ b/src/receiving.cc @@ -0,0 +1,1818 @@ +#include "connections.hh" +#include "info.hh" + +#include "stubs.hh" + +#include + +bool CommandAllowed(TConnection *Connection, int Command){ + if(Connection == NULL){ + error("CommandAllowed: Connection ist NULL.\n"); + return false; + } + + if(Connection->State == CONNECTION_GAME){ + return Command != CL_CMD_LOGIN_REQUEST + && Command != CL_CMD_LOGIN; + }else if(Connection->State == CONNECTION_DEAD || Connection->State == CONNECTION_LOGOUT){ + return Command == CL_CMD_LOGOUT + || Command == CL_CMD_PING + || Command == CL_CMD_BUG_REPORT + || Command == CL_CMD_ERROR_FILE_ENTRY; + }else{ + error("CommandAllowed: Ungültiger Verbindungsstatus %d bei Kommando %d.\n", + Connection->State, Command); + return false; + } +} + +bool CheckSpecialCoordinates(int Command, int x, int y, int z, bool AllowInventoryAny){ + if(x == 0xFFFF){ // SPECIAL_COORDINATE ? + if(y == INVENTORY_ANY){ + return AllowInventoryAny; + }else if((y >= INVENTORY_FIRST && y <= INVENTORY_LAST) + || (y >= CONTAINER_FIRST && y <= CONTAINER_LAST)){ + return true; + }else{ + print(3, "CheckSpecialCoordinates: Ungültige Koordinaten" + " [%d,%d,%d] bei Kommando %d.\n", x, y, z, Command); + return false; + } + }else{ + return IsOnMap(x, y, z); + } +} + +bool CheckVisibility(int Command, TConnection *Connection, int x, int y, int z){ + if(Connection == NULL){ + error("CheckVisibility: Connection ist NULL.\n"); + return false; + } + + bool Result = Connection->IsVisible(x, y, z); + if(!Result){ + int PlayerX, PlayerY, PlayerZ; + Connection->GetPosition(&PlayerX, &PlayerY, &PlayerZ); + print(3, "CheckVisibility: Feld [%d,%d,%d] ist von [%d,%d,%d]" + " aus nicht sichtbar bei Kommando %d.\n", + x, y, z, PlayerX, PlayerY, PlayerZ, Command); + } + return Result; +} + +bool CheckObjectType(int Command, int TypeID){ + bool Result = ObjectTypeExists(TypeID); + if(!Result){ + print(3, "CheckObjectType: Ungültiger Objekttyp %d bei Kommando %d.\n", + TypeID, Command); + } + return Result; +} + +ObjectType GetObjectType(int Command, int TypeID){ + // TODO(fusion): Isn't this already done by `ObjectType::setTypeID` ? + ObjectType ObjType(0); + if(CheckObjectType(Command, TypeID)){ + ObjType.setTypeID(TypeID); + } + return ObjType; +} + +void CQuitGame(TConnection *Connection, TReadBuffer *Buffer){ + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + Connection->Logout(0, true); + return; + } + + switch(Player->LogoutPossible()){ + case 0:{ + Player->ToDoClear(); + Connection->Logout(0, true); + break; + } + + case 1:{ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You may not logout during or immediately after a fight!"); + break; + } + case 2:{ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You may not logout here!"); + break; + } + + default:{ + // TODO(fusion): The original function would also logout the player + // on this case which feels weird, specially when you can't have any + // other result from `LogoutPossible`. + error("CQuitGame: Ungültiger Rückgabewert von LogoutPossible.\n"); + break; + } + } +} + +void CPing(TConnection *Connection, TReadBuffer *Buffer){ + // NOTE(fusion): Its a no-op because it's already encoded in `Connection::TimeStamp`. +} + +void CGoPath(TConnection *Connection, TReadBuffer *Buffer){ + // TODO(fusion): Sometimes we check, sometimes we don't. It should always be + // valid since these functions are all called from within `ReceiveData` which + // also checks it. + if(Connection == NULL){ + error("CGoPath: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + if(Player->ToDoClear()){ + SendSnapback(Connection); + } + + int Steps = (int)Buffer->readByte(); + TToDoEntry TD = {}; + TD.Code = TDGo; + TD.Go.x = Player->posx; + TD.Go.y = Player->posy; + TD.Go.z = Player->posz; + try{ + for(int i = 0; i < Steps; i += 1){ + // NOTE(fusion): For whatever reason these directions are not the same + // we use internally. + switch(Buffer->readByte()){ + case 1: TD.Go.x += 1; break; // EAST + case 2: TD.Go.x += 1; TD.Go.y -= 1; break; // NORTHEAST + case 3: TD.Go.y -= 1; break; // NORTH + case 4: TD.Go.x -= 1; TD.Go.y -= 1; break; // NORTHWEST + case 5: TD.Go.x -= 1; break; // WEST + case 6: TD.Go.x -= 1; TD.Go.y += 1; break; // SOUTHWEST + case 7: TD.Go.y += 1; break; // SOUTH + case 8: TD.Go.x += 1; TD.Go.y += 1; break; // SOUTHEAST + default:{ + continue; + } + } + + Player->ToDoAdd(TD); + } + + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoYield(); + } +} + +void CGoDirection(TConnection *Connection, int OffsetX, int OffsetY){ + if(Connection == NULL){ + error("CGoDirection: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + try{ + if(Player->ToDoClear()){ + SendSnapback(Connection); + } + + TToDoEntry TD = {}; + TD.Code = TDGo; + TD.Go.x = Player->posx + OffsetX; + TD.Go.y = Player->posy + OffsetY; + TD.Go.z = Player->posz; + Player->ToDoAdd(TD); + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoYield(); + } +} + +void CGoStop(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CGoStop: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player != NULL){ + Player->ToDoStop(); + } +} + +void CRotate(TConnection *Connection, int Direction){ + if(Connection == NULL){ + error("CRotate: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + try{ + Player->ToDoRotate(Direction); + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoYield(); + } +} + +void CMoveObject(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CMoveObject: Connection ist NULL.\n"); + return; + } + + // TODO(fusion): I'm just following the convention being used. There is a + // comment in `ReceiveData` but the fact that there is only one command in + // a packet makes it unnecessary to "consume" all command's parameters. + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int OrigX = Buffer->readWord(); + int OrigY = Buffer->readWord(); + int OrigZ = Buffer->readByte(); + int TypeID = Buffer->readWord(); + uint8 RNum = Buffer->readByte(); + int DestX = Buffer->readWord(); + int DestY = Buffer->readWord(); + int DestZ = Buffer->readByte(); + uint8 Count = Buffer->readByte(); + + ObjectType Type = GetObjectType(CL_CMD_MOVE_OBJECT, TypeID); + if(Type.isMapContainer() || (Type.getFlag(CUMULATIVE) && Count == 0)){ + return; + } + + if(!CheckSpecialCoordinates(CL_CMD_MOVE_OBJECT, OrigX, OrigY, OrigZ, false) + || !CheckSpecialCoordinates(CL_CMD_MOVE_OBJECT, DestX, DestY, DestZ, true)){ + return; + } + + if((OrigX != 0xFFFF && !CheckVisibility(CL_CMD_MOVE_OBJECT, Connection, OrigX, OrigY, OrigZ)) + || (DestX != 0xFFFF && !CheckVisibility(CL_CMD_MOVE_OBJECT, Connection, DestX, DestY, DestZ))){ + return; + } + + // TODO(fusion): `RNum` usage in this context will only be used inside + // `GetObject` for indexing containers. For some reason I thought the + // Z coordinate was also used for that. Perhaps they're set to the same + // value. + if(OrigX != 0xFFFF){ + RNum = 1; + } + + try{ + Player->ToDoMove(OrigX, OrigY, OrigZ, Type, RNum, DestX, DestY, DestZ, Count); + Player->ToDoStart(); + }catch(RESULT r){ + if(r != NOERROR){ + SendResult(Connection, r); + Player->ToDoYield(); + } + } +} + +void CTradeObject(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CTradeObject: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ObjX = Buffer->readWord(); + int ObjY = Buffer->readWord(); + int ObjZ = Buffer->readByte(); + int TypeID = Buffer->readWord(); + uint8 RNum = Buffer->readByte(); + uint32 TradePartner = Buffer->readQuad(); + + ObjectType Type = GetObjectType(CL_CMD_TRADE_OBJECT, TypeID); + if(Type.isMapContainer()){ + return; + } + + if(!CheckSpecialCoordinates(CL_CMD_TRADE_OBJECT, ObjX, ObjY, ObjZ, false)){ + return; + } + + if(ObjX != 0xFFFF && !CheckVisibility(CL_CMD_TRADE_OBJECT, Connection, ObjX, ObjY, ObjZ)){ + return; + } + + // TODO(fusion): Same as `CMoveObject`. + if(ObjX != 0xFFFF){ + RNum = 1; + } + + try{ + Player->ToDoTrade(ObjX, ObjY, ObjZ, Type, RNum, TradePartner); + Player->ToDoStart(); + }catch(RESULT r){ + if(r != NOERROR){ + SendResult(Connection, r); + Player->ToDoYield(); + } + } +} + +void CInspectTrade(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CInspectTrade: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + bool OwnOffer = (Buffer->readByte() == 0); + int Position = Buffer->readByte(); + Object Obj = Player->InspectTrade(OwnOffer, Position); + if(Obj.exists()){ + try{ + Look(Player->ID, Obj); + }catch(RESULT r){ + SendResult(Connection, r); + } + } +} + +void CAcceptTrade(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CAcceptTrade: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player != NULL){ + Player->AcceptTrade(); + } +} + +void CRejectTrade(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CRejectTrade: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player != NULL){ + Player->RejectTrade(); + } +} + +void CUseObject(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CUseObject: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ObjX = Buffer->readWord(); + int ObjY = Buffer->readWord(); + int ObjZ = Buffer->readByte(); + int TypeID = Buffer->readWord(); + uint8 RNum = Buffer->readByte(); + uint8 Dummy = Buffer->readByte(); + + ObjectType Type = GetObjectType(CL_CMD_USE_OBJECT, TypeID); + if(Type.isMapContainer() || Type.getFlag(MULTIUSE)){ + return; + } + + if(Type.getFlag(CONTAINER) && Dummy >= NARRAY(TPlayer::OpenContainer)){ + return; + } + + if(!CheckSpecialCoordinates(CL_CMD_USE_OBJECT, ObjX, ObjY, ObjZ, false)){ + return; + } + + if(ObjX != 0xFFFF && !CheckVisibility(CL_CMD_USE_OBJECT, Connection, ObjX, ObjY, ObjZ)){ + return; + } + + try{ + Player->ToDoWait(100); + Player->ToDoUse(1, ObjX, ObjY, ObjZ, Type, RNum, Dummy, 0, 0, 0, 0, 0); + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoClear(); + Player->ToDoYield(); + } +} + +void CUseTwoObjects(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CUseTwoObjects: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ObjX1 = Buffer->readWord(); + int ObjY1 = Buffer->readWord(); + int ObjZ1 = Buffer->readByte(); + int TypeID1 = Buffer->readWord(); + uint8 RNum1 = Buffer->readByte(); + int ObjX2 = Buffer->readWord(); + int ObjY2 = Buffer->readWord(); + int ObjZ2 = Buffer->readByte(); + int TypeID2 = Buffer->readWord(); + uint8 RNum2 = Buffer->readByte(); + + ObjectType Type1 = GetObjectType(CL_CMD_USE_TWO_OBJECTS, TypeID1); + ObjectType Type2 = GetObjectType(CL_CMD_USE_TWO_OBJECTS, TypeID2); + if(Type1.isMapContainer() || Type2.isMapContainer() || !Type1.getFlag(MULTIUSE)){ + return; + } + + if(!CheckSpecialCoordinates(CL_CMD_USE_TWO_OBJECTS, ObjX1, ObjY1, ObjZ1, false) + || !CheckSpecialCoordinates(CL_CMD_USE_TWO_OBJECTS, ObjX2, ObjY2, ObjZ2, false)){ + return; + } + + if((ObjX1 != 0xFFFF && !CheckVisibility(CL_CMD_USE_TWO_OBJECTS, Connection, ObjX1, ObjY1, ObjZ1)) + || (ObjX2 != 0xFFFF && !CheckVisibility(CL_CMD_USE_TWO_OBJECTS, Connection, ObjX2, ObjY2, ObjZ2))){ + return; + } + + try{ + Player->ToDoWait(100); + Player->ToDoUse(2, ObjX1, ObjY1, ObjZ1, Type1, RNum1, 0, + ObjX2, ObjY2, ObjZ2, Type2, RNum2); + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoClear(); + Player->ToDoYield(); + } +} + +void CUseOnCreature(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CUseOnCreature: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ObjX = Buffer->readWord(); + int ObjY = Buffer->readWord(); + int ObjZ = Buffer->readByte(); + int TypeID = Buffer->readWord(); + uint8 RNum = Buffer->readByte(); + uint32 TargetID = Buffer->readQuad(); + + // TODO(fusion): Check `Type.getFlag(MULTIUSE)`? + ObjectType Type = GetObjectType(CL_CMD_USE_ON_CREATURE, TypeID); + if(Type.isMapContainer()){ + return; + } + + if(!CheckSpecialCoordinates(CL_CMD_USE_ON_CREATURE, ObjX, ObjY, ObjZ, false)){ + return; + } + + if(ObjX != 0xFFFF && !CheckVisibility(CL_CMD_USE_ON_CREATURE, Connection, ObjX, ObjY, ObjZ)){ + return; + } + + TCreature *Target = GetCreature(TargetID); + if(Target == NULL || Target->Type == PLAYER){ + return; + } + + if(!CheckVisibility(CL_CMD_USE_ON_CREATURE, Connection, + Target->posx, Target->posy, Target->posz)){ + return; + } + + // TODO(fusion): Isn't this already checked with `CheckVisibility`? It also + // checks against the terminal offset which is not a distance semantically. + int DistanceX = std::abs(Target->posx - Player->posx); + int DistanceY = std::abs(Target->posy - Player->posy); + if(DistanceX >= Connection->TerminalOffsetX + || DistanceY >= Connection->TerminalOffsetY){ + SendResult(Connection, OUTOFRANGE); + return; + } + + Object Obj = GetObject(Player->ID, ObjX, ObjY, ObjZ, RNum, Type); + if(!Obj.exists() || !Target->CrObject.exists()){ + SendResult(Connection, NOTACCESSIBLE); + return; + } + + try{ + Player->ToDoWait(100); + Player->ToDoUse(2, Obj, Target->CrObject); + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoClear(); + Player->ToDoYield(); + } +} + +void CTurnObject(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CTurnObject: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ObjX = Buffer->readWord(); + int ObjY = Buffer->readWord(); + int ObjZ = Buffer->readByte(); + int TypeID = Buffer->readWord(); + uint8 RNum = Buffer->readByte(); + + // TODO(fusion): Check `Type.getFlag(ROTATE)`? + ObjectType Type = GetObjectType(CL_CMD_TURN_OBJECT, TypeID); + if(Type.isMapContainer()){ + return; + } + + if(!CheckSpecialCoordinates(CL_CMD_TURN_OBJECT, ObjX, ObjY, ObjZ, false)){ + return; + } + + if(ObjX != 0xFFFF && !CheckVisibility(CL_CMD_TURN_OBJECT, Connection, ObjX, ObjY, ObjZ)){ + return; + } + + try{ + Player->ToDoWait(100); + Player->ToDoTurn(ObjX, ObjY, ObjZ, Type, RNum); + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoClear(); + Player->ToDoYield(); + } +} + +void CCloseContainer(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CCloseContainer: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ContainerNr = Buffer->readByte(); + if(ContainerNr < NARRAY(TPlayer::OpenContainer)){ + Player->SetOpenContainer(ContainerNr, NONE); + SendCloseContainer(Connection, ContainerNr); + } +} + +void CUpContainer(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CUpContainer: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ContainerNr = Buffer->readByte(); + if(ContainerNr < NARRAY(TPlayer::OpenContainer)){ + Object Con = Player->GetOpenContainer(ContainerNr); + if(Con != NONE){ + Object Up = Con.getContainer(); + ObjectType UpType = Up.getObjectType(); + if(!UpType.isMapContainer() && !UpType.isBodyContainer()){ + Player->SetOpenContainer(ContainerNr, Up); + SendContainer(Connection, ContainerNr); + }else{ + Player->SetOpenContainer(ContainerNr, NONE); + SendCloseContainer(Connection, ContainerNr); + } + } + } +} + +void CEditText(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CEditText: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + Object Obj = Buffer->readQuad(); + if(!Obj.exists()){ + SendResult(Connection, NOTACCESSIBLE); + return; + } + + ObjectType ObjType = Obj.getObjectType(); + if(!ObjType.getFlag(WRITE) + && (!ObjType.getFlag(WRITEONCE) || Obj.getAttribute(TEXTSTRING) != 0)){ + SendResult(Connection, NOTACCESSIBLE); + return; + } + + char Text[4096]; + Buffer->readString(Text, sizeof(Text)); + int TextLength = (int)strlen(Text); + int MaxLength = (ObjType.getFlag(WRITE) + ? (int)ObjType.getAttribute(MAXLENGTH) + : (int)ObjType.getAttribute(MAXLENGTHONCE)); + if(TextLength >= MaxLength){ + SendResult(Connection, NOROOM); + return; + } + + try{ + EditText(Player->ID, Obj, Text); + }catch(RESULT r){ + SendResult(Connection, r); + } +} + +void CEditList(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CEditList: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + char Text[4096]; + int Type = Buffer->readByte(); + uint32 ID = Buffer->readQuad(); + Buffer->readString(Text, sizeof(Text)); + if(Type == GUESTLIST){ + ChangeGuests((uint16)ID, Player, Text); + }else if(Type == SUBOWNERLIST){ + ChangeSubowners((uint16)ID, Player, Text); + }else if(Type == DOORLIST){ + Object Door = ID; + if(!Door.exists()){ + SendResult(Connection, NOTACCESSIBLE); + return; + } + + ObjectType DoorType = Door.getObjectType(); + if(!DoorType.getFlag(NAMEDOOR) || !DoorType.getFlag(TEXT)){ + SendResult(Connection, NOTACCESSIBLE); + return; + } + + ChangeNameDoor(Door, Player, Text); + }else{ + error("CEditList: Unbekannter Typ %d.\n", Type); + } +} + +void CLookAtPoint(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CLookAtPoint: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ObjX = Buffer->readWord(); + int ObjY = Buffer->readWord(); + int ObjZ = Buffer->readByte(); + if(!CheckSpecialCoordinates(CL_CMD_LOOK_AT_POINT, ObjX, ObjY, ObjZ, false)){ + return; + } + + if(ObjX != 0xFFFF && !CheckVisibility(CL_CMD_LOOK_AT_POINT, Connection, ObjX, ObjY, ObjZ)){ + return; + } + + int RNum = (ObjX == 0xFFFF ? ObjZ : -1); + Object Obj = GetObject(Player->ID, ObjX, ObjY, ObjZ, RNum, 0); + if(Obj.exists()){ + try{ + Look(Player->ID, Obj); + }catch(RESULT r){ + SendResult(Connection, r); + } + } +} + +void CTalk(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CTalk: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + print(3, "CTalk: Der Verbindung ist kein Spieler zugeordnet.\n"); + return; + } + + int Mode = Buffer->readByte(); + if(Mode != TALK_SAY + && Mode != TALK_WHISPER + && Mode != TALK_YELL + && Mode != TALK_PRIVATE_MESSAGE + && Mode != TALK_CHANNEL_CALL + && Mode != TALK_GAMEMASTER_REQUEST + && Mode != TALK_GAMEMASTER_ANSWER + && Mode != TALK_PLAYER_ANSWER + && Mode != TALK_GAMEMASTER_BROADCAST + && Mode != TALK_GAMEMASTER_CHANNELCALL + && Mode != TALK_GAMEMASTER_MESSAGE + && Mode != TALK_ANONYMOUS_BROADCAST + && Mode != TALK_ANONYMOUS_CHANNELCALL + && Mode != TALK_ANONYMOUS_MESSAGE){ + print(3, "CTalk: Unbekannter Sprechmodus %d.\n", Mode); + return; + } + + char Addressee[30] = {}; + if(Mode == TALK_PRIVATE_MESSAGE + || Mode == TALK_GAMEMASTER_ANSWER + || Mode == TALK_GAMEMASTER_MESSAGE + || Mode == TALK_ANONYMOUS_MESSAGE){ + Buffer->readString(Addressee, sizeof(Addressee)); + if(Addressee[0] == 0){ + print(3, "CTalk: Adressat nicht angegeben.\n"); + return; + } + } + + int Channel = 0; + if(Mode == TALK_CHANNEL_CALL + || Mode == TALK_GAMEMASTER_CHANNELCALL + || Mode == TALK_ANONYMOUS_CHANNELCALL){ + Channel = Buffer->readWord(); + if(Channel >= GetNumberOfChannels()){ + print(3, "CTalk: Ungültiger Kanal %d.\n", Channel); + return; + } + + snprintf(Addressee, sizeof(Addressee), "%d", Channel); + } + + char Text[256]; + Buffer->readString(Text, sizeof(Text)); + if(Text[0] == 0){ + print(3, "CTalk: Kein Text.\n"); + return; + } + + if(findFirst(Text, '\n') != NULL){ + error("CTalk: %s verwendet Newlines (%d,%s)\n", Player->Name, Mode, Text); + return; + } + + if(Mode == TALK_GAMEMASTER_ANSWER && !CheckRight(Player->ID, READ_GAMEMASTER_CHANNEL)){ + Mode = TALK_PRIVATE_MESSAGE; + }else if(Mode == TALK_GAMEMASTER_BROADCAST && !CheckRight(Player->ID, GAMEMASTER_BROADCAST)){ + Mode = TALK_SAY; + }else if(Mode == TALK_GAMEMASTER_CHANNELCALL && !CheckRight(Player->ID, GAMEMASTER_BROADCAST)){ + Mode = TALK_CHANNEL_CALL; + }else if(Mode == TALK_GAMEMASTER_MESSAGE && !CheckRight(Player->ID, GAMEMASTER_BROADCAST)){ + Mode = TALK_PRIVATE_MESSAGE; + }else if(Mode == TALK_ANONYMOUS_BROADCAST && !CheckRight(Player->ID, ANONYMOUS_BROADCAST)){ + Mode = TALK_SAY; + }else if(Mode == TALK_ANONYMOUS_CHANNELCALL && !CheckRight(Player->ID, ANONYMOUS_BROADCAST)){ + Mode = TALK_CHANNEL_CALL; + }else if(Mode == TALK_ANONYMOUS_MESSAGE && !CheckRight(Player->ID, ANONYMOUS_BROADCAST)){ + Mode = TALK_PRIVATE_MESSAGE; + } + + if(Mode == TALK_YELL && Player->Skills[SKILL_LEVEL]->Get() <= 1){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You may not yell as long as you are on level 1."); + return; + } + + if(Mode == TALK_CHANNEL_CALL && Player->Skills[SKILL_LEVEL]->Get() <= 1){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You may not speak into channels as long as you are on level 1."); + return; + } + + if(Mode == TALK_CHANNEL_CALL + || Mode == TALK_GAMEMASTER_CHANNELCALL + || Mode == TALK_ANONYMOUS_CHANNELCALL){ + if(Channel == CHANNEL_RULEVIOLATIONS){ + print(3, "ChannelCall für GM-Request-Queue.\n"); + return; + } + + if(!ChannelSubscribed(Channel, Player->ID)){ + Addressee[0] = 0; + Mode = TALK_SAY; + } + } + + if(Mode == TALK_CHANNEL_CALL && Channel == CHANNEL_HELP + && CheckRight(Player->ID, HIGHLIGHT_HELP_CHANNEL)){ + Mode = TALK_HIGHLIGHT_CHANNELCALL; + Player->TutorActivities += 1; + print(3, "Aktvitätspunkt für %s.\n", Player->Name); + } + + if(Mode == TALK_PLAYER_ANSWER){ + if(Player->Request == 0){ + return; + } + + if(Player->RequestProcessingGamemaster == 0){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Please wait until your request is answered."); + return; + } + + TPlayer *Gamemaster = GetPlayer(Player->RequestProcessingGamemaster); + if(Gamemaster == NULL){ + SendCloseRequest(Connection); + Player->Request = 0; + return; + } + + strcpy(Addressee, Gamemaster->Name); + } + + if(Mode == TALK_GAMEMASTER_REQUEST){ + if(Player->Request != 0){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You have already submitted a request." + " Please wait until it is answered."); + return; + } + + Player->Request = AddDynamicString(Text); + Player->RequestTimestamp = RoundNr; + Player->RequestProcessingGamemaster = 0; + CreateGamemasterRequest(Player->Name, Text); + }else{ + try{ + Player->ToDoTalk(Mode, Addressee, Text, true); + Player->ToDoStart(); + }catch(RESULT r){ + SendResult(Connection, r); + Player->ToDoYield(); + } + } +} + +void CGetChannels(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CGetChannels: Connection ist NULL.\n"); + return; + } + + SendChannels(Connection); +} + +void CJoinChannel(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CJoinChannel: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int Channel = Buffer->readWord(); + if(Channel < GetNumberOfChannels()){ + try{ + bool OwnChannel = JoinChannel(Channel, Player->ID); + if(Channel == CHANNEL_RULEVIOLATIONS){ + SendOpenRequestQueue(Connection); + SendExistingRequests(Connection); + }else if(OwnChannel){ + SendOpenOwnChannel(Connection, Channel); + }else{ + SendOpenChannel(Connection, Channel); + } + }catch(RESULT r){ + print(3, "Spieler darf Kanal nicht hören.\n"); + } + } +} + +void CLeaveChannel(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CLeaveChannel: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int Channel = Buffer->readWord(); + if(Channel < GetNumberOfChannels()){ + LeaveChannel(Channel, Player->ID, true); + } +} + +void CPrivateChannel(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CPrivateChannel: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + char Name[30]; + Buffer->readString(Name, sizeof(Name)); + if(Name[0] == 0){ + return; + } + + uint32 CharacterID = GetCharacterID(Name); + if(CharacterID == 0){ + SendResult(Connection, PLAYERNOTEXISTING); + return; + } + + if(CharacterID == Player->ID){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You cannot set up a private message channel with yourself."); + return; + } + + SendPrivateChannel(Connection, GetCharacterName(Name)); +} + +void CProcessRequest(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CProcessRequest: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL || !ChannelAvailable(CHANNEL_RULEVIOLATIONS, Player->ID)){ + return; + } + + char Name[30]; + Buffer->readString(Name, sizeof(Name)); + if(Name[0] == 0){ + return; + } + + TPlayer *Other; + if(IdentifyPlayer(Name, true, true, &Other) != 0){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Player is not online any more."); + SendFinishRequest(Connection, Name); + return; + } + + if(Other->Request == 0 || Other->RequestProcessingGamemaster != 0){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Request has already been processed."); + SendFinishRequest(Connection, Name); + return; + } + + Other->RequestProcessingGamemaster = Player->ID; + DeleteGamemasterRequest(Other->Name); +} + +void CRemoveRequest(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CRemoveRequest: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL || !ChannelAvailable(CHANNEL_RULEVIOLATIONS, Player->ID)){ + return; + } + + char Name[30]; + Buffer->readString(Name, sizeof(Name)); + if(Name[0] == 0){ + return; + } + + TPlayer *Other; + if(IdentifyPlayer(Name, true, true, &Other) != 0){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Player is not online any more."); + SendFinishRequest(Connection, Name); + return; + } + + if(Other->Request != 0){ + if(Other->RequestProcessingGamemaster == Player->ID){ + Other->Request = 0; + SendCloseRequest(Other->Connection); + }else if(Other->RequestProcessingGamemaster == 0){ + DeleteGamemasterRequest(Other->Name); + } + } +} + +void CCancelRequest(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CCancelRequest: Connection ist NULL.\n"); + return; + } + + // TODO(fusion): Does this mean regular players can't cancel their requests? + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL || !ChannelAvailable(CHANNEL_RULEVIOLATIONS, Player->ID)){ + return; + } + + if(Player->Request != 0){ + Player->Request = 0; + if(Player->RequestProcessingGamemaster != 0){ + TPlayer *Gamemaster = GetPlayer(Player->RequestProcessingGamemaster); + if(Gamemaster != NULL){ + SendFinishRequest(Gamemaster->Connection, Player->Name); + } + }else{ + DeleteGamemasterRequest(Player->Name); + } + } +} + +void CSetTactics(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CSetTactics: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int AttackMode = Buffer->readByte(); + int ChaseMode = Buffer->readByte(); + int SecureMode = Buffer->readByte(); + + if(AttackMode != ATTACK_MODE_OFFENSIVE + && AttackMode != ATTACK_MODE_BALANCED + && AttackMode != ATTACK_MODE_DEFENSIVE){ + print(3, "CSetTactics: Ungültiger Angriffsmodus %d.\n", AttackMode); + return; + } + + if(ChaseMode != CHASE_MODE_NONE + && ChaseMode != CHASE_MODE_CLOSE){ + print(3, "CSetTactics: Ungültiger Verfolgungsmodus %d.\n", ChaseMode); + return; + } + + if(SecureMode != SECURE_MODE_DISABLED + && SecureMode != SECURE_MODE_ENABLED){ + print(3, "CSetTactics: Ungültiger Sicherheitsmodus %d.\n", SecureMode); + return; + } + + Player->Combat.SetAttackMode((uint8)AttackMode); + Player->Combat.SetChaseMode((uint8)ChaseMode); + Player->Combat.SetSecureMode((uint8)SecureMode); +} + +void CAttack(TConnection *Connection, TReadBuffer *Buffer, bool Follow){ + if(Connection == NULL){ + error("CAttack: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + uint32 TargetID = Buffer->readQuad(); + try{ + Player->Combat.SetAttackDest(TargetID, Follow); + Player->ToDoAttack(); + Player->ToDoStart(); + }catch(RESULT r){ + if(r != NOERROR){ + SendResult(Connection, r); + Player->ToDoYield(); + } + } +} + +void CInviteToParty(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CInviteToParty: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + uint32 GuestID = Buffer->readQuad(); + TCreature *Guest = GetCreature(GuestID); + if(Guest == NULL){ + return; + } + + if(!CheckVisibility(CL_CMD_INVITE_TO_PARTY, Connection, + Guest->posx, Guest->posy, Guest->posz)){ + return; + } + + InviteToParty(Player->ID, GuestID); +} + +void CJoinParty(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CJoinParty: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + uint32 HostID = Buffer->readQuad(); + JoinParty(Player->ID, HostID); +} + +void CRevokeInvitation(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CRevokeInvitation: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + if(Player->GetPartyLeader(false) == 0){ + print(3, "Spieler ist kein Mitglied einer Jagdgruppe.\n"); + return; + } + + uint32 GuestID = Buffer->readQuad(); + RevokeInvitation(Player->ID, GuestID); +} + +void CPassLeadership(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CPassLeadership: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + if(Player->GetPartyLeader(false) == 0){ + print(3, "Spieler ist kein Mitglied einer Jagdgruppe.\n"); + return; + } + + uint32 NewLeaderID = Buffer->readQuad(); + PassLeadership(Player->ID, NewLeaderID); +} + +void CLeaveParty(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CLeaveParty: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + if(Player->GetPartyLeader(false) == 0){ + print(3, "Spieler ist kein Mitglied einer Jagdgruppe.\n"); + return; + } + + LeaveParty(Player->ID, false); +} + +void COpenChannel(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("COpenChannel: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + try{ + OpenChannel(Player->ID); + }catch(RESULT r){ + SendResult(Connection, r); + } +} + +void CInviteToChannel(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CInviteToChannel: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + char Name[30]; + Buffer->readString(Name, sizeof(Name)); + if(Name[0] == 0){ + print(2, "CInviteToChannel: Kein Name angegeben.\n"); + return; + } + + try{ + InviteToChannel(Player->ID, Name); + }catch(RESULT r){ + SendResult(Connection, r); + } +} + +void CExcludeFromChannel(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CExcludeFromChannel: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + // TODO(fusion): The original function didn check if name was empty but it + // is probably a good idea. + char Name[30]; + Buffer->readString(Name, sizeof(Name)); + if(Name[0] == 0){ + print(2, "CInviteToChannel: Kein Name angegeben.\n"); + return; + } + + try{ + ExcludeFromChannel(Player->ID, Name); + }catch(RESULT r){ + SendResult(Connection, r); + } +} + +void CCancel(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CCancel: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + try{ + Player->Combat.StopAttack(0); + if(Player->ToDoClear()){ + SendSnapback(Connection); + } + }catch(RESULT r){ + // no-op + } + + Player->ToDoYield(); +} + +void CRefreshField(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CRefreshField: Connection ist NULL.\n"); + return; + } + + int FieldX = Buffer->readWord(); + int FieldY = Buffer->readWord(); + int FieldZ = Buffer->readByte(); + + if(!IsOnMap(FieldX, FieldY, FieldZ)){ + return; + } + + if(!CheckVisibility(CL_CMD_REFRESH_FIELD, Connection, FieldX, FieldY, FieldZ)){ + return; + } + + SendFieldData(Connection, FieldX, FieldY, FieldZ); +} + +void CRefreshContainer(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CRefreshContainer: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + int ContainerNr = Buffer->readByte(); + if(ContainerNr < NARRAY(TPlayer::OpenContainer)){ + Object Con = Player->GetOpenContainer(ContainerNr); + if(Con != NONE){ + SendContainer(Connection, ContainerNr); + } + } +} + +void CGetOutfit(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CGetOutfit: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + if(CheckRight(Player->ID, GAMEMASTER_OUTFIT)){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You may not change your outfit."); + return; + } + + SendOutfit(Connection); +} + +void CSetOutfit(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CSetOutfit: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + TOutfit NewOutfit = {}; + NewOutfit.OutfitID = Buffer->readWord(); + Buffer->readBytes(NewOutfit.Colors, sizeof(NewOutfit.Colors)); + + int FirstOutfit = (Player->Sex == 1) ? 128 : 136; + int LastOutfit = (Player->Sex == 1) ? 131 : 139; + if(CheckRight(Player->ID, PREMIUM_ACCOUNT)){ + LastOutfit += 3; + } + + if(NewOutfit.OutfitID < FirstOutfit || NewOutfit.OutfitID > LastOutfit){ + if(Player->Sex == 1){ + print(3, "CSetOutfit: Ungültiges Outfit %d für Männer.\n", NewOutfit.OutfitID); + }else{ + print(3, "CSetOutfit: Ungültiges Outfit %d für Frauen.\n", NewOutfit.OutfitID); + } + return; + } + + if(NewOutfit.Colors[0] > 132 + || NewOutfit.Colors[1] > 132 + || NewOutfit.Colors[2] > 132 + || NewOutfit.Colors[3] > 132){ + print(3, "CSetOutfit: Ungültige Farbe für Outfit.\n"); + return; + } + + if(Player->Outfit == Player->OrgOutfit){ + Player->Outfit = NewOutfit; + AnnounceChangedCreature(Player->ID, CREATURE_OUTFIT_CHANGED); + } + + Player->OrgOutfit = NewOutfit; +} + +void CAddBuddy(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CAddBuddy: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + char Name[30]; + Buffer->readString(Name, sizeof(Name)); + if(Name[0] != 0){ + Player->AddBuddy(Name); + } +} + +void CRemoveBuddy(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CRemoveBuddy: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + uint32 CharacterID = Buffer->readQuad(); + Player->RemoveBuddy(CharacterID); +} + +// NOTE(fusion): These logging functions were out of control. It's not necessarily +// better now but it is way simpler and do we even need any special formatting? + +void CBugReport(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CBugReport: Connection ist NULL.\n"); + return; + } + + char Text[1024]; + Buffer->readString(Text, sizeof(Text)); + + bool Empty = true; + for(int i = 0; Text[i] != 0; i += 1){ + if(!isprint(Text[i])){ + Text[i] = 0; + break; + }else if(!isSpace(Text[i])){ + Empty = false; + } + } + + if(Empty){ + return; + } + + // NOTE(fusion): `ctime` will already add a new line character which is why + // there is none in this first `Log` call. + int PlayerX, PlayerY, PlayerZ; + time_t Time = time(NULL); + Connection->GetPosition(&PlayerX, &PlayerY, &PlayerZ); + Log("bugreport", "%s - %d/%d - [%d,%d,%d] - %s", + Connection->GetName(), + Connection->TerminalType, + Connection->TerminalVersion, + PlayerX, PlayerY, PlayerZ, + ctime(&Time)); + Log("bugreport", "%s\n", Text); + Log("bugreport", "---------------------------------------------------------------------------\n"); + + SendMessage(Connection, TALK_STATUS_MESSAGE, "Comment sent."); +} + +void CRuleViolation(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CRuleViolation: Connection ist NULL.\n"); + return; + } + + TPlayer *Player = Connection->GetPlayer(); + if(Player == NULL){ + return; + } + + char Name[30]; + char Comment[200]; + Buffer->readString(Name, sizeof(Name)); + int Reason = Buffer->readByte(); + int Action = Buffer->readByte(); + Buffer->readString(Comment, sizeof(Comment)); + uint32 StatementID = Buffer->readQuad(); + bool IPBanishment = Buffer->readByte() != 0; + + if(!CheckBanishmentRight(Player->ID, Reason, Action) + || (IPBanishment && !CheckRight(Player->ID, IP_BANISHMENT))){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You have no authorization for this action."); + return; + } + + if(Comment[0] == 0){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Please provide a comment for this report."); + return; + } + + if(Action == 6 && StatementID == 0){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Please provide a statement for this rule violation."); + return; + } + + TPlayer *Criminal; + const char *IPAddress = NULL; + bool IgnoreGamemasters = !CheckRight(Player->ID, READ_GAMEMASTER_CHANNEL); + if(IdentifyPlayer(Name, false, IgnoreGamemasters, &Criminal) == 0){ + if(CheckRight(Criminal->ID, NO_BANISHMENT)){ + if(Action == 1 || Action == 3 || Action == 5){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "This name has already been approved."); + return; + } + + if(Action != 6){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "You may not report a god or gamemaster."); + return; + } + } + + strcpy(Name, Criminal->Name); + IPAddress = Criminal->IPAddress; + }else{ + if(GetCharacterID(Name) == 0){ + SendResult(Connection, PLAYERNOTEXISTING); + return; + } + + strcpy(Name, GetCharacterName(Name)); + if(IPBanishment){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Player is not online. No IP address was banished."); + IPBanishment = false; + } + } + + int NumberOfStatements = 0; + vector *ReportedStatements = NULL; + bool HasStatement = ((Reason >= 9 && Reason <= 27) || Reason == 29); + if(HasStatement && StatementID != 0){ + uint32 ListenerID = (Action != 6 ? Player->ID : 0); + int Context = GetCommunicationContext(ListenerID, StatementID, + &NumberOfStatements, &ReportedStatements); + if(Context == 1){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Statement is unknown. Perhaps it is too old?"); + return; + }else if(Context == 2){ + SendMessage(Connection, TALK_FAILURE_MESSAGE, + "Statement has already been reported."); + return; + } + } + + PunishmentOrder(Player, Name,IPAddress, Reason, Action, Comment, + NumberOfStatements, ReportedStatements, StatementID, IPBanishment); +} + +void CErrorFileEntry(TConnection *Connection, TReadBuffer *Buffer){ + if(Connection == NULL){ + error("CErrorFileEntry: Connection ist NULL.\n"); + return; + } + + char Title[64]; + char Date[32]; + char Stack[2048]; + char Comment[512]; + Buffer->readString(Title, sizeof(Title)); + Buffer->readString(Date, sizeof(Date)); + Buffer->readString(Stack, sizeof(Stack)); + Buffer->readString(Comment, sizeof(Comment)); + if(Stack[0] == 0 && Comment[0] == 0){ + return; + } + + // NOTE(fusion): `ctime` will already add a new line character which is why + // there is none in this first `Log` call. + int PlayerX, PlayerY, PlayerZ; + time_t Time = time(NULL); + Connection->GetPosition(&PlayerX, &PlayerY, &PlayerZ); + Log("client-error", "%s - %d/%d - [%d,%d,%d] - %s", + Connection->GetName(), + Connection->TerminalType, + Connection->TerminalVersion, + PlayerX, PlayerY, PlayerZ, + ctime(&Time)); + Log("client-error", "%s\n", Title); + Log("client-error", "%s\n", Date); + + if(Stack[0] != 0){ + Log("client-error", "\n"); + Log("client-error", "%s\n", Stack); + } + + if(Comment[0] != 0){ + Log("client-error", "\n"); + Log("client-error", "%s\n", Comment); + } + + Log("client-error","---------------------------------------------------------------------------\n"); +} + +void ReceiveData(TConnection *Connection){ + if(Connection == NULL){ + error("ReceiveData: Connection ist NULL.\n"); + return; + } + + if(Connection->InDataSize <= 0){ + error("ReceiveData: Keine Daten vorhanden.\n"); + return; + } + + if((Connection->InDataSize + 2) > (int)sizeof(Connection->InData)){ + error("ReceiveData: Zu große Paketlänge %d.\n", Connection->InDataSize); + return; + } + + // TODO(fusion): I thought the client would actually pack multiple commands + // in the same packet. Perhaps not until some later version? + + // IMPORTANT(fusion): The actual payload size is in the buffer's first two + // bytes which is why we start reading from offset two. + TReadBuffer Buffer(Connection->InData + 2, Connection->InDataSize); + + uint8 Command; + try{ + Command = Buffer.readByte(); + }catch(const char *str){ + error("ReceiveData: Fehler beim Auslesen des Kommandos (%s).\n", str); + return; + } + + if(Connection->State == CONNECTION_LOGIN){ + if(Command != CL_CMD_LOGIN){ + error("ReceiveData: Falsches Login-Kommando %d.\n", Command); + }else if(!Connection->JoinGame(&Buffer)){ + Log("game", "Einloggen gescheitert.\n"); + SendResult(Connection, LOGINERROR); + TPlayer *Player = Connection->GetPlayer(); + if(Player != NULL){ + DecrementIsOnlineOrder(Player->ID); + }else{ + error("ReceiveData: Einloggen gescheitert und keine Kreatur bekannt.\n"); + } + Connection->Disconnect(); + } + return; + } + + if(!CommandAllowed(Connection, Command)){ + return; + } + + Connection->ResetTimer(Command); + try{ + switch(Command){ + case CL_CMD_LOGOUT: CQuitGame(Connection, &Buffer); break; + case CL_CMD_PING: CPing(Connection, &Buffer); break; + case CL_CMD_GO_PATH: CGoPath(Connection, &Buffer); break; + case CL_CMD_GO_NORTH: CGoDirection(Connection, 0, -1); break; + case CL_CMD_GO_EAST: CGoDirection(Connection, 1, 0); break; + case CL_CMD_GO_SOUTH: CGoDirection(Connection, 0, 1); break; + case CL_CMD_GO_WEST: CGoDirection(Connection, -1, 0); break; + case CL_CMD_GO_STOP: CGoStop(Connection, &Buffer); break; + case CL_CMD_GO_NORTHEAST: CGoDirection(Connection, 1, -1); break; + case CL_CMD_GO_SOUTHEAST: CGoDirection(Connection, 1, 1); break; + case CL_CMD_GO_SOUTHWEST: CGoDirection(Connection, -1, 1); break; + case CL_CMD_GO_NORTHWEST: CGoDirection(Connection, -1, -1); break; + case CL_CMD_ROTATE_NORTH: CRotate(Connection, DIRECTION_NORTH); break; + case CL_CMD_ROTATE_EAST: CRotate(Connection, DIRECTION_EAST); break; + case CL_CMD_ROTATE_SOUTH: CRotate(Connection, DIRECTION_SOUTH); break; + case CL_CMD_ROTATE_WEST: CRotate(Connection, DIRECTION_WEST); break; + case CL_CMD_MOVE_OBJECT: CMoveObject(Connection, &Buffer); break; + case CL_CMD_TRADE_OBJECT: CTradeObject(Connection, &Buffer); break; + case CL_CMD_INSPECT_TRADE: CInspectTrade(Connection, &Buffer); break; + case CL_CMD_ACCEPT_TRADE: CAcceptTrade(Connection, &Buffer); break; + case CL_CMD_REJECT_TRADE: CRejectTrade(Connection, &Buffer); break; + case CL_CMD_USE_OBJECT: CUseObject(Connection, &Buffer); break; + case CL_CMD_USE_TWO_OBJECTS: CUseTwoObjects(Connection, &Buffer); break; + case CL_CMD_USE_ON_CREATURE: CUseOnCreature(Connection, &Buffer); break; + case CL_CMD_TURN_OBJECT: CTurnObject(Connection, &Buffer); break; + case CL_CMD_CLOSE_CONTAINER: CCloseContainer(Connection, &Buffer); break; + case CL_CMD_UP_CONTAINER: CUpContainer(Connection, &Buffer); break; + case CL_CMD_EDIT_TEXT: CEditText(Connection, &Buffer); break; + case CL_CMD_EDIT_LIST: CEditList(Connection, &Buffer); break; + case CL_CMD_LOOK_AT_POINT: CLookAtPoint(Connection, &Buffer); break; + case CL_CMD_TALK: CTalk(Connection, &Buffer); break; + case CL_CMD_GET_CHANNELS: CGetChannels(Connection, &Buffer); break; + case CL_CMD_JOIN_CHANNEL: CJoinChannel(Connection, &Buffer); break; + case CL_CMD_LEAVE_CHANNEL: CLeaveChannel(Connection, &Buffer); break; + case CL_CMD_PRIVATE_CHANNEL: CPrivateChannel(Connection, &Buffer); break; + case CL_CMD_PROCESS_REQUEST: CProcessRequest(Connection, &Buffer); break; + case CL_CMD_REMOVE_REQUEST: CRemoveRequest(Connection, &Buffer); break; + case CL_CMD_CANCEL_REQUEST: CCancelRequest(Connection, &Buffer); break; + case CL_CMD_SET_TACTICS: CSetTactics(Connection, &Buffer); break; + case CL_CMD_ATTACK: CAttack(Connection, &Buffer, false); break; + case CL_CMD_FOLLOW: CAttack(Connection, &Buffer, true); break; + case CL_CMD_INVITE_TO_PARTY: CInviteToParty(Connection, &Buffer); break; + case CL_CMD_JOIN_PARTY: CJoinParty(Connection, &Buffer); break; + case CL_CMD_REVOKE_INVITATION: CRevokeInvitation(Connection, &Buffer); break; + case CL_CMD_PASS_LEADERSHIP: CPassLeadership(Connection, &Buffer); break; + case CL_CMD_LEAVE_PARTY: CLeaveParty(Connection, &Buffer); break; + case CL_CMD_OPEN_CHANNEL: COpenChannel(Connection, &Buffer); break; + case CL_CMD_INVITE_TO_CHANNEL: CInviteToChannel(Connection, &Buffer); break; + case CL_CMD_EXCLUDE_FROM_CHANNEL: CExcludeFromChannel(Connection, &Buffer); break; + case CL_CMD_CANCEL: CCancel(Connection, &Buffer); break; + case CL_CMD_REFRESH_FIELD: CRefreshField(Connection, &Buffer); break; + case CL_CMD_REFRESH_CONTAINER: CRefreshContainer(Connection, &Buffer); break; + case CL_CMD_GET_OUTFIT: CGetOutfit(Connection, &Buffer); break; + case CL_CMD_SET_OUTFIT: CSetOutfit(Connection, &Buffer); break; + case CL_CMD_ADD_BUDDY: CAddBuddy(Connection, &Buffer); break; + case CL_CMD_REMOVE_BUDDY: CRemoveBuddy(Connection, &Buffer); break; + case CL_CMD_BUG_REPORT: CBugReport(Connection, &Buffer); break; + case CL_CMD_RULE_VIOLATION: CRuleViolation(Connection, &Buffer); break; + case CL_CMD_ERROR_FILE_ENTRY: CErrorFileEntry(Connection, &Buffer); break; + default:{ + print(3, "Unbekanntes Kommando %d.\n", Command); + break; + } + } + }catch(const char *str){ + error("Fehler beim Auslesen der Daten für Kommando %d (%s).\n", Command, str); + } +} + +void ReceiveData(void){ + TConnection *Connection = GetFirstConnection(); + while(Connection != NULL){ + if(Connection->Live() && Connection->WaitingForACK){ + ReceiveData(Connection); + Connection->WaitingForACK = false; + // TODO(fusion): It could have been disconnected inside `ReceiveData`? + if(Connection->Live()){ + kill(Connection->GetPID(), SIGUSR1); + } + } + Connection = GetNextConnection(); + } +} + +void InitReceiving(void){ + // no-op +} + +void ExitReceiving(void){ + // no-op +} diff --git a/src/sending.cc b/src/sending.cc index 52c3e28..14551da 100644 --- a/src/sending.cc +++ b/src/sending.cc @@ -1091,8 +1091,8 @@ void SendEditText(TConnection *Connection, Object Obj){ char SpellbookBuffer[4096] = {}; if(ObjType.getFlag(WRITE) || ObjType.getFlag(WRITEONCE)){ MaxLength = (ObjType.getFlag(WRITE) - ? ObjType.getAttribute(MAXLENGTH) - : ObjType.getAttribute(MAXLENGTHONCE)); + ? (int)ObjType.getAttribute(MAXLENGTH) + : (int)ObjType.getAttribute(MAXLENGTHONCE)); MaxLength -= 1; Text = GetDynamicString(Obj.getAttribute(TEXTSTRING)); Editor = GetDynamicString(Obj.getAttribute(EDITOR)); @@ -1532,12 +1532,12 @@ void SendPrivateChannel(TConnection *Connection, const char *Name){ FinishSendData(Connection); } -void SendOpenRequest(TConnection *Connection){ +void SendOpenRequestQueue(TConnection *Connection){ if(!BeginSendData(Connection)){ return; } - SendByte(Connection, SV_CMD_OPEN_REQUEST); + SendByte(Connection, SV_CMD_OPEN_REQUEST_QUEUE); SendWord(Connection, (uint16)CHANNEL_RULEVIOLATIONS); FinishSendData(Connection); } @@ -1724,6 +1724,29 @@ void BroadcastMessage(int Mode, const char *Text, ...){ } } +void CreateGamemasterRequest(const char *Name, const char *Text){ + if(Name == NULL){ + error("CreateGamemasterRequest: Name ist NULL.\n"); + return; + } + + if(Text == NULL){ + error("CreateGamemasterRequest: Name ist NULL.\n"); + return; + } + + TConnection *Connection = GetFirstConnection(); + while(Connection != NULL){ + if(Connection->Live()){ + TPlayer *Player = Connection->GetPlayer(); + if(Player != NULL && ChannelSubscribed(CHANNEL_RULEVIOLATIONS, Player->ID)){ + SendTalk(Connection, 0, Name, TALK_GAMEMASTER_REQUEST, Text, 0); + } + } + Connection = GetNextConnection(); + } +} + void DeleteGamemasterRequest(const char *Name){ if(Name == NULL){ error("DeleteGamemasterRequest: Name ist NULL.\n"); diff --git a/src/stubs.hh b/src/stubs.hh index a7bd80d..e3b694e 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -18,6 +18,9 @@ typedef void TSendMailsFunction(TPlayerData *PlayerData); extern void AbortWriter(void); extern void AddBuddyOrder(TCreature *Creature, uint32 CharacterID); extern void RemoveBuddyOrder(TCreature *Creature, uint32 BuddyID); +extern void ChangeGuests(uint16 HouseID, TPlayer *Player, const char *Text); +extern void ChangeSubowners(uint16 HouseID, TPlayer *Player, const char *Text); +extern void ChangeNameDoor(Object Door, TPlayer *Player, const char *Text); extern void ChangeNPCState(TCreature *Npc, int NewState, bool Stimulus); extern void CharacterDeathOrder(TCreature *Creature, int OldLevel, uint32 Offender, const char *Remark, bool Unjustified); @@ -47,7 +50,6 @@ extern void PunishmentOrder(TCreature *Creature, const char *Name, const char *I int Reason, int Action, const char *Comment, int NumberOfStatements, vector *ReportedStatements, uint32 StatementID, bool IPBanishment); -extern void ReceiveData(void); extern void SavePlayerData(TPlayerData *Slot); extern bool LoadPlayerData(TPlayerData *Slot); extern bool PlayerDataExists(uint32 CharacterID); -- cgit v1.2.3