diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-06-19 03:13:48 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-06-19 03:13:48 -0300 |
| commit | bd3a6a04601749cbde007eaabf803fb602ee2783 (patch) | |
| tree | 476b89932627aa73ad88de22d37e4617bbdb1795 /src | |
| parent | e5b8aadd493b8b5df4ed661f2491de33d634b001 (diff) | |
| download | game-bd3a6a04601749cbde007eaabf803fb602ee2783.tar.gz game-bd3a6a04601749cbde007eaabf803fb602ee2783.zip | |
beginning of `communication.cc`
Diffstat (limited to 'src')
| -rw-r--r-- | src/common.hh | 2 | ||||
| -rw-r--r-- | src/communication.cc | 335 | ||||
| -rw-r--r-- | src/communication.hh | 31 | ||||
| -rw-r--r-- | src/connections.hh (renamed from src/connection.hh) | 13 | ||||
| -rw-r--r-- | src/cr.hh | 2 | ||||
| -rw-r--r-- | src/crmain.cc | 1 | ||||
| -rw-r--r-- | src/crplayer.cc | 2 | ||||
| -rw-r--r-- | src/crypto.cc | 3 | ||||
| -rw-r--r-- | src/crypto.hh | 58 | ||||
| -rw-r--r-- | src/main.cc | 19 | ||||
| -rw-r--r-- | src/operate.cc | 13 | ||||
| -rw-r--r-- | src/query.hh | 6 | ||||
| -rw-r--r-- | src/shm.cc | 2 | ||||
| -rw-r--r-- | src/strings.cc | 2 | ||||
| -rw-r--r-- | src/stubs.hh | 5 | ||||
| -rw-r--r-- | src/threads.cc (renamed from src/thread.cc) | 2 | ||||
| -rw-r--r-- | src/threads.hh (renamed from src/thread.hh) | 6 | ||||
| -rw-r--r-- | src/utils.cc (renamed from src/util.cc) | 0 |
18 files changed, 459 insertions, 43 deletions
diff --git a/src/common.hh b/src/common.hh index 384d76e..e0bfb81 100644 --- a/src/common.hh +++ b/src/common.hh @@ -150,7 +150,7 @@ void GetAmbiente(int *Brightness, int *Color); uint32 GetRoundAtTime(int Hour, int Minute); uint32 GetRoundForNextMinute(void); -// util.cc +// utils.cc // ============================================================================= typedef void TErrorFunction(const char *Text); typedef void TPrintFunction(int Level, const char *Text); diff --git a/src/communication.cc b/src/communication.cc new file mode 100644 index 0000000..dc28566 --- /dev/null +++ b/src/communication.cc @@ -0,0 +1,335 @@ +#include "communication.hh" +#include "config.hh" +#include "connections.hh" +#include "containers.hh" +#include "crypto.hh" +#include "query.hh" +#include "threads.hh" + +#include "stubs.hh" + +#include <signal.h> + +#define MAX_COMMUNICATION_THREADS 1100 +#define THREAD_OWN_STACK_SIZE ((int)KB(64)) + +static int TERMINAL_VERSION[3] = {770, 770, 770}; +static int TCPSocket; +static ThreadHandle AcceptorThread; +static pid_t AcceptorThreadPID; +static int ActiveConnections; + +static Semaphore RSAMutex(1); +static TRSAPrivateKey PrivateKey; + +static TQueryManagerConnectionPool QueryManagerConnectionPool(10); +static int LoadHistory[360]; +static int LoadHistoryPointer; +static int TotalLoad; +static int TotalSend; +static int TotalRecv; +static uint32 LagEnd; +static uint32 EarliestFreeAccountAdmissionRound; +static store<TWaitinglistEntry, 100> Waitinglist; +static TWaitinglistEntry *WaitinglistHead; + +static Semaphore CommunicationThreadMutex(1); +static bool UseOwnStacks; +static uint8 CommunicationThreadStacks[MAX_COMMUNICATION_THREADS][THREAD_OWN_STACK_SIZE]; +static pid_t LastUsingCommunicationThread[MAX_COMMUNICATION_THREADS]; +static int FreeCommunicationThreadStacks[MAX_COMMUNICATION_THREADS]; +static int NumberOfFreeCommunicationThreadStacks; + +// Communication Thread Stacks +// ============================================================================= +void GetCommunicationThreadStack(int *StackNumber, void **Stack){ + *StackNumber = -1; + *Stack = NULL; + + if(!UseOwnStacks){ + error("GetCommunicationThreadStack: Bibliothek unterstützt keine eigenen Stacks.\n"); + return; + } + + CommunicationThreadMutex.down(); + for(int i = 0; i < NumberOfFreeCommunicationThreadStacks; i += 1){ + int FreeStack = FreeCommunicationThreadStacks[i]; + if(LastUsingCommunicationThread[FreeStack] == 0 + || kill(LastUsingCommunicationThread[FreeStack], 0) == -1){ + // NOTE(fusion): A little swap and pop action. + NumberOfFreeCommunicationThreadStacks -= 1; + FreeCommunicationThreadStacks[i] = FreeCommunicationThreadStacks[NumberOfFreeCommunicationThreadStacks]; + + *StackNumber = FreeStack; + *Stack = CommunicationThreadStacks[FreeStack]; + break; + } + } + CommunicationThreadMutex.up(); +} + +void AttachCommunicationThreadStack(int StackNumber){ + LastUsingCommunicationThread[StackNumber] = getpid(); +} + +void ReleaseCommunicationThreadStack(int StackNumber){ + CommunicationThreadMutex.down(); + FreeCommunicationThreadStacks[NumberOfFreeCommunicationThreadStacks] = StackNumber; + NumberOfFreeCommunicationThreadStacks += 1; + CommunicationThreadMutex.up(); +} + +void InitCommunicationThreadStacks(void){ + if(UseOwnStacks){ + memset(CommunicationThreadStacks, 0xAA, sizeof(CommunicationThreadStacks)); + for(int i = 0; i < MAX_COMMUNICATION_THREADS; i += 1){ + LastUsingCommunicationThread[i] = 0; + FreeCommunicationThreadStacks[i] = i; + } + NumberOfFreeCommunicationThreadStacks = MAX_COMMUNICATION_THREADS; + } +} + +void ExitCommunicationThreadStacks(void){ + if(UseOwnStacks){ + if(NumberOfFreeCommunicationThreadStacks != MAX_COMMUNICATION_THREADS){ + error("FreeCommunicationThreadStacks: Nicht alle Stacks freigegeben.\n"); + } + + int HighestStackAddress = -1; + int LowestStackAddress = THREAD_OWN_STACK_SIZE; + for(int i = 0; i < MAX_COMMUNICATION_THREADS; i += 1){ + for(int Addr = 0; Addr < THREAD_OWN_STACK_SIZE; Addr += 1){ + if(CommunicationThreadStacks[i][Addr] != 0xAA){ + if(Addr < LowestStackAddress){ + LowestStackAddress = Addr; + } + + if(Addr > HighestStackAddress){ + HighestStackAddress = Addr; + } + } + } + } + + // NOTE(fusion): It seems we want to track whether the stack size is + // too small but I'd argue the method is not very robust. + if((HighestStackAddress - LowestStackAddress) > (THREAD_OWN_STACK_SIZE / 2)){ + error("Maximale Stack-Ausdehnung: %d..%d\n", LowestStackAddress, HighestStackAddress); + } + } +} + +// Load History +// ============================================================================= +void InitLoadHistory(void){ + for(int i = 0; i < NARRAY(LoadHistory); i += 1){ + LoadHistory[i] = 0; + } + LoadHistoryPointer = 0; + TotalLoad = 0; + TotalSend = 0; + TotalRecv = 0; + LagEnd = 0; + EarliestFreeAccountAdmissionRound = 0; + InitLog("netload"); +} + +bool LagDetected(void){ + return RoundNr <= LagEnd; +} + +void NetLoad(int Amount, bool Send){ + CommunicationThreadMutex.down(); + if(Send){ + TotalSend += Amount; + }else{ + TotalRecv += Amount; + } + CommunicationThreadMutex.up(); +} + +void NetLoadSummary(void){ + CommunicationThreadMutex.down(); + Log("netload", "gesendet: %d Bytes.\n", TotalSend); + Log("netload", "empfangen: %d Bytes.\n", TotalRecv); + TotalSend = 0; + TotalRecv = 0; + CommunicationThreadMutex.up(); +} + +void NetLoadCheck(void){ + static int LastRecv; + + int DeltaRecv = TotalRecv - LastRecv; + LastRecv = TotalRecv; + if(DeltaRecv < 0){ + return; + } + + int DeltaRecvPerPlayer = 0; + int PlayersOnline = GetPlayersOnline(); + if(PlayersOnline > 0){ + DeltaRecvPerPlayer = DeltaRecv / PlayersOnline; + } + + TotalLoad -= LoadHistory[LoadHistoryPointer]; + TotalLoad += DeltaRecvPerPlayer; + LoadHistory[LoadHistoryPointer] = DeltaRecvPerPlayer; + LoadHistoryPointer += 1; + if(LoadHistoryPointer >= NARRAY(LoadHistory)){ + LoadHistoryPointer = 0; + } + + // NOTE(fusion): Running this lag check only makes sense if `LoadHistory` + // is filled up which won't be the case until this function executes at + // least as many times as there are entries in `LoadHistory`. + // Looking at `AdvanceGame`, we see that this function is called every + // 10 rounds, giving us the value of `EarliestLagCheckRound`. + constexpr uint32 EarliestLagCheckRound = 10 * NARRAY(LoadHistory); + if(RoundNr >= EarliestLagCheckRound && PlayersOnline >= 50){ + int AvgDeltaRecvPerPlayer = (TotalLoad / NARRAY(LoadHistory)); + if(DeltaRecvPerPlayer < (AvgDeltaRecvPerPlayer / 2)){ + Log("game", "Lag erkannt!\n"); + LagEnd = RoundNr + 30; + + // NOTE(fusion): This formula looks weird but when we take `MaxPlayers` + // and `PremiumPlayerBuffer` to be 950 and 150 (taken from the config + // file, although their values are now loaded from the database), we + // get a line with negative values when the number of players online + // is less than 650, and exactly 60 when it is 950. Since the delay + // is 60 when `PremiumPlayerBuffer` is zero, I don't think this is a + // coincidence. + int FreeAccountAdmissionDelay = 60; + if(PremiumPlayerBuffer != 0){ + FreeAccountAdmissionDelay = (PlayersOnline + PremiumPlayerBuffer * 2 - MaxPlayers); + FreeAccountAdmissionDelay = (FreeAccountAdmissionDelay * 30) / PremiumPlayerBuffer; + if(FreeAccountAdmissionDelay < 0){ + FreeAccountAdmissionDelay = 0; + } + } + + uint32 FreeAccountAdmissionRound = RoundNr + (uint32)FreeAccountAdmissionDelay; + if(EarliestFreeAccountAdmissionRound < FreeAccountAdmissionRound){ + EarliestFreeAccountAdmissionRound = FreeAccountAdmissionRound; + } + + TConnection *Connection = GetFirstConnection(); + while(Connection != NULL){ + if(Connection->Live()){ + Connection->EmergencyPing(); + } + Connection = GetNextConnection(); + } + } + } +} + +// Communication Handling +// ============================================================================= +bool WriteToSocket(TConnection *Connection, uint8 *Buffer, int Size){ + // TODO(fusion): I think `Size` refers to the payload but `Buffer` also has + // room for writing the packet's length at the beginning and enough room for + // padding (supposedly). + + while((Size % 8) != 0){ + Buffer[Size + 2] = rand_r(&Connection->RandomSeed); + Size += 1; + } + + for(int i = 0; i < Size; i += 8){ + Connection->SymmetricKey.encrypt(&Buffer[i + 2]); + } + + TWriteBuffer WriteBuffer(Buffer, 2); + WriteBuffer.writeWord((uint16)Size); + + int Attempts = 50; + int BytesToWrite = Size + 2; + uint8 *WritePtr = Buffer; + while(BytesToWrite > 0){ + int ret = (int)write(Connection->GetSocket(), WritePtr, BytesToWrite); + if(ret > 0){ + BytesToWrite -= ret; + WritePtr += ret; + }else if(ret == 0){ + // TODO(fusion): Can this even happen? + error("WriteToSocket: Fehler %d beim Senden an Socket %d.\n", + errno, Connection->GetSocket()); + return false; + }else{ + if(errno == EINTR){ + continue; + } + + if(errno != EAGAIN || Attempts <= 0){ + if(errno == ECONNRESET || errno == EPIPE || errno == EAGAIN){ + Log("game", "Verbindung an Socket %d zusammengebrochen.\n", + Connection->GetSocket()); + }else{ + error("WriteToSocket: Fehler %d beim Senden an Socket %d.\n", + errno, Connection->GetSocket()); + } + return false; + } + + DelayThread(0, 100000); + Attempts -= 1; + } + } + + // TODO(fusion): Do we add 50 extra bytes to account for TCP segment headers? + // This does make sense If we assume packets are split into ~2.5 segments on + // average, with each segment header being 20 bytes. + NetLoad(Size + 50, true); + return true; +} + +bool SendLoginMessage(TConnection *Connection, int Type, char *Message, int WaitingTime){ + // TODO(fusion): + // LOGIN_MESSAGE_ERROR = 20 + // LOGIN_MESSAGE_? = 21 + // LOGIN_MESSAGE_WAITING_LIST = 22 + if(Type != 20 && Type != 21 && Type != 22){ + error("SendLoginMessage: Ungültiger Meldungstyp %d.\n", Type); + return true; + } + + if(Message == NULL){ + error("SendLoginMessage: Message ist NULL.\n"); + return true; + } + + if(Type == 22 && (WaitingTime < 0 || WaitingTime > UINT8_MAX)){ + error("SendLoginMessage: Ungültige Wartezeit %d.\n", WaitingTime); + return true; + } + + if(strlen(Message) > 290){ + error("SendLoginMessage: Botschaft zu lang (%s).\n", Message); + return true; + } + + // TODO(fusion): Writing output messages should have more robust helpers + // to avoid all sorts of memory bugs but since we're only doing it in two + // places from what I've seen, I'm not actually gonna bother (for now at + // least). + + // NOTE(fusion): We make sure we leave two extra bytes at the beginning so + // `WriteToSocket` can write the packet size. We also make sure that the + // remainder of the buffer has a size that is multiple of 8 so `WriteToSocket` + // can add any necessary padding for XTEA encryption without overflowing it. + uint8 Data[302]; // 2 + 300 + TWriteBuffer WriteBuffer(Data + 2, sizeof(Data) - 2); + WriteBuffer.writeWord(0); + WriteBuffer.writeByte((uint8)Type); + WriteBuffer.writeString(Message); + if(Type == 22){ + WriteBuffer.writeByte(WaitingTime); + } + + int Size = WriteBuffer.Position; + WriteBuffer.Position = 0; + WriteBuffer.writeWord((uint16)(Size - 2)); + return WriteToSocket(Connection, Data, Size); +} diff --git a/src/communication.hh b/src/communication.hh new file mode 100644 index 0000000..a54f704 --- /dev/null +++ b/src/communication.hh @@ -0,0 +1,31 @@ +#ifndef TIBIA_COMMUNICATION_HH_ +#define TIBIA_COMMUNICATION_HH_ 1 + +#include "common.hh" +#include "connections.hh" + +struct TWaitinglistEntry { + TWaitinglistEntry *Next; + char Name[30]; + uint32 NextTry; + bool FreeAccount; + bool Newbie; + bool Sleeping; +}; + +void GetCommunicationThreadStack(int *StackNumber, void **Stack); +void AttachCommunicationThreadStack(int StackNumber); +void ReleaseCommunicationThreadStack(int StackNumber); +void InitCommunicationThreadStacks(void); +void ExitCommunicationThreadStacks(void); + +void InitLoadHistory(void); +bool LagDetected(void); +void NetLoad(int Amount, bool Send); +void NetLoadSummary(void); +void NetLoadCheck(void); + +bool WriteToSocket(TConnection *Connection, uint8 *Buffer, int Size); +bool SendLoginMessage(TConnection *Connection, int Type, char *Message, int WaitingTime); + +#endif //TIBIA_COMMUNICATION_HH_ diff --git a/src/connection.hh b/src/connections.hh index 5e2b1ba..0aef82b 100644 --- a/src/connection.hh +++ b/src/connections.hh @@ -2,6 +2,7 @@ #define TIBIA_CONNECTION_HH_ 1 #include "common.hh" +#include "crypto.hh" #include "enums.hh" struct TConnection; @@ -22,6 +23,16 @@ struct TConnection { const char *GetIPAddress(void); void Die(void); KNOWNCREATURESTATE KnownCreature(uint32 CreatureID, bool UpdateFollows); + int GetSocket(void); + void EmergencyPing(void); + + // TODO(fusion): Maybe rename this later? + bool Live(void) const { + return this->State == CONNECTION_LOGIN + || this->State == CONNECTION_GAME + || this->State == CONNECTION_DEAD + || this->State == CONNECTION_LOGOUT; + } // DATA // ================= @@ -45,7 +56,7 @@ struct TConnection { pid_t PID; int Socket; char IPAddress[16]; - // TXTEASymmetricKey SymmetricKey; // TODO + TXTEASymmetricKey SymmetricKey; bool ConnectionIsOk; bool ClosingIsDelayed; uint8 field23_0x4852; @@ -2,7 +2,7 @@ #define TIBIA_CREATURE_HH_ 1 #include "common.hh" -#include "connection.hh" +#include "connections.hh" #include "containers.hh" #include "enums.hh" #include "map.hh" diff --git a/src/crmain.cc b/src/crmain.cc index a98f33e..6193515 100644 --- a/src/crmain.cc +++ b/src/crmain.cc @@ -1,4 +1,5 @@ #include "cr.hh" +#include "communication.hh" #include "config.hh" #include "enums.hh" #include "info.hh" diff --git a/src/crplayer.cc b/src/crplayer.cc index 24fcd56..5c28855 100644 --- a/src/crplayer.cc +++ b/src/crplayer.cc @@ -3,7 +3,7 @@ #include "info.hh" #include "operate.hh" #include "query.hh" -#include "thread.hh" +#include "threads.hh" #include "stubs.hh" diff --git a/src/crypto.cc b/src/crypto.cc new file mode 100644 index 0000000..b6df866 --- /dev/null +++ b/src/crypto.cc @@ -0,0 +1,3 @@ +#include "crypto.hh" + +// TODO diff --git a/src/crypto.hh b/src/crypto.hh new file mode 100644 index 0000000..e90996c --- /dev/null +++ b/src/crypto.hh @@ -0,0 +1,58 @@ +#ifndef TIBIA_CRYPTO_HH_ +#define TIBIA_CRYPTO_HH_ 1 + +#include "common.hh" + +// TODO(fusion): We might want to scrap this implementation and use OpenSSL instead. + +struct vlong_flex_unit{ + uint32 n; + uint32 *a; + uint32 z; +}; + +struct vlong_value: vlong_flex_unit { + uint32 share; +}; + +struct vlong{ + vlong_value *value; + int negative; +}; + +struct vlong_montgomery{ + vlong R; + vlong R1; + vlong m; + vlong n1; + vlong T; + vlong k; + uint32 N; +}; + +struct TRSAPrivateKey{ + TRSAPrivateKey(void); + ~TRSAPrivateKey(void); + void decrypt(uint8 *Data); // single 128 bytes block + + // DATA + // ================= + vlong m_PrimeP; + vlong m_PrimeQ; + vlong m_U; + vlong m_DP; + vlong m_DQ; +}; + +struct TXTEASymmetricKey{ + TXTEASymmetricKey(void); + ~TXTEASymmetricKey(void); + void encrypt(uint8 *Data); // single 8 bytes block + void decrypt(uint8 *Data); // single 8 bytes block + + // DATA + // ================= + uint32 m_SymmetricKey[4]; +}; + +#endif //TIBIA_CRYPTO_HH_ diff --git a/src/main.cc b/src/main.cc index c0180c2..8d5fcf5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,4 +1,5 @@ #include "common.hh" +#include "communication.hh" #include "config.hh" #include "info.hh" #include "map.hh" @@ -327,23 +328,7 @@ static void AdvanceGame(int Delay){ OldAmbiente = Brightness; TConnection *Connection = GetFirstConnection(); while(Connection != NULL){ - // TODO(fusion): This is probably an inlined function that checks - // whether the connection is still going. The exact decompiled condition - // was `Connection->State - CONDITION_LOGIN < 4` but I think that's - // just a compiler optimization that wouldn't work properly on the - // decompiled version. That comparison in the disassembly is unsigned - // (`JBE`) but the enum is signed which would probably generate an - // invalid signed comparison (`JLE`). - // - // MOV EAX, dword ptr [Connection + Connection->State] - // SUB EAX, 0x3 - // CMP EAX, 0x3 - // JBE ... -> SendAmbiente(Connection) - // - if(Connection->State == CONNECTION_LOGIN - || Connection->State == CONNECTION_GAME - || Connection->State == CONNECTION_DEAD - || Connection->State == CONNECTION_LOGOUT){ + if(Connection->Live()){ SendAmbiente(Connection); } Connection = GetNextConnection(); diff --git a/src/operate.cc b/src/operate.cc index 7dc1fef..aa061a8 100644 --- a/src/operate.cc +++ b/src/operate.cc @@ -2393,12 +2393,7 @@ void Talk(uint32 CreatureID, int Mode, const char *Addressee, const char *Text, uint32 StatementID = LogCommunication(CreatureID, Mode, 0, Text); TConnection *Connection = GetFirstConnection(); while(Connection != NULL){ - // TODO(fusion): Same as `AdvanceGame`. Definitely some inlined - // function to check whether the connection is in a valid state. - if(Connection->State == CONNECTION_LOGIN - || Connection->State == CONNECTION_GAME - || Connection->State == CONNECTION_DEAD - || Connection->State == CONNECTION_LOGOUT){ + if(Connection->Live()){ SendTalk(Connection, LogListener(StatementID, Connection->GetPlayer()), Creature->Name, Mode, Text, 0); @@ -2409,11 +2404,7 @@ void Talk(uint32 CreatureID, int Mode, const char *Addressee, const char *Text, }else if(Mode == TALK_ANONYMOUS_BROADCAST){ TConnection *Connection = GetFirstConnection(); while(Connection != NULL){ - // TODO(fusion): Same as above. - if(Connection->State == CONNECTION_LOGIN - || Connection->State == CONNECTION_GAME - || Connection->State == CONNECTION_DEAD - || Connection->State == CONNECTION_LOGOUT){ + if(Connection->Live()){ SendMessage(Connection, TALK_ADMIN_MESSAGE, Text); } diff --git a/src/query.hh b/src/query.hh index f9cd8de..7d3c2a8 100644 --- a/src/query.hh +++ b/src/query.hh @@ -2,7 +2,7 @@ #define TIBIA_QUERY_HH_ 1 #include "common.hh" -#include "thread.hh" +#include "threads.hh" struct TQueryManagerConnection{ TQueryManagerConnection(int QueryBufferSize); @@ -28,6 +28,10 @@ struct TQueryManagerConnection{ }; struct TQueryManagerConnectionPool{ + TQueryManagerConnectionPool(int Connections); + + // DATA + // ================= int NumberOfConnections; TQueryManagerConnection *QueryManagerConnection; bool *QueryManagerConnectionFree; @@ -1,7 +1,7 @@ #include "common.hh" #include "config.hh" #include "enums.hh" -#include "thread.hh" +#include "threads.hh" #include "stubs.hh" diff --git a/src/strings.cc b/src/strings.cc index aef9a81..d0bfe70 100644 --- a/src/strings.cc +++ b/src/strings.cc @@ -218,7 +218,7 @@ void ExitStrings(void){ // String Utility // ============================================================================= // TODO(fusion): I'm not sure why we have these separate from the other string -// utility defined in `util.cc`. We should probably just move them all here. +// utility defined in `utils.cc`. We should probably just move them all here. bool IsCountable(const char *s){ if(strncmp(s, "some ", 5) == 0){ diff --git a/src/stubs.hh b/src/stubs.hh index 561fc95..4363b0a 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -3,7 +3,7 @@ #include "common.hh" #include "enums.hh" -#include "connection.hh" +#include "connections.hh" #include "cr.hh" #include "magic.hh" #include "map.hh" @@ -36,12 +36,9 @@ extern void InitLog(const char *ProtocolName); extern bool IsInvited(uint16 HouseID, TPlayer *Player, int TimeStamp); extern void KickGuest(uint16 HouseID, TPlayer *Host, TPlayer *Guest); extern void KillStatisticsOrder(int NumberOfRaces, const char *RaceNames, int *KilledPlayers, int *KilledCreatures); -extern bool LagDetected(void); extern void LoadSectorOrder(int SectorX, int SectorY, int SectorZ); extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3); extern void LogoutOrder(TPlayer *Player); -extern void NetLoadCheck(void); -extern void NetLoadSummary(void); extern void PrepareHouseCleanup(void); extern void FinishHouseCleanup(void); extern void PlayerlistOrder(int NumberOfPlayers, char *PlayerNames, int *PlayerLevels, int *PlayerProfessions); diff --git a/src/thread.cc b/src/threads.cc index 95ce1a6..a7acb41 100644 --- a/src/thread.cc +++ b/src/threads.cc @@ -1,4 +1,4 @@ -#include "thread.hh" +#include "threads.hh" struct TThreadStarter { ThreadFunction *Function; diff --git a/src/thread.hh b/src/threads.hh index 17e46e9..9eafe11 100644 --- a/src/thread.hh +++ b/src/threads.hh @@ -1,5 +1,5 @@ -#ifndef TIBIA_THREAD_HH_ -#define TIBIA_THREAD_HH_ 1 +#ifndef TIBIA_THREADS_HH_ +#define TIBIA_THREADS_HH_ 1 #include "common.hh" #include <pthread.h> @@ -30,4 +30,4 @@ struct Semaphore { pthread_cond_t condition; }; -#endif //TIBIA_THREAD_HH_ +#endif //TIBIA_THREADS_HH_ diff --git a/src/util.cc b/src/utils.cc index 4a3523b..4a3523b 100644 --- a/src/util.cc +++ b/src/utils.cc |
