linux Makefile + fix most compilation problems

I wanted to see if the compiler had any problems with the code
so far and added a few stub definitions so that each file would
properly compile. We still fail when linking but we're able to to
find and fix compile time errors.
This commit is contained in:
fusion32 2025-05-25 22:37:57 -03:00
parent 5f883a8017
commit ad8213f355
27 changed files with 1238 additions and 871 deletions

75
Makefile Normal file
View File

@ -0,0 +1,75 @@
SRCDIR = src
BUILDDIR = build
OUTPUTEXE = game
CC = g++
CFLAGS = -m64 -fno-strict-aliasing -Wall -Wextra -Wno-unused-parameter -Wno-format-truncation -std=c++11 -DOS_LINUX=1 -DARCH_X64=1 -D_CRT_SECURE_NO_WARNINGS=1
LFLAGS = -Wl,-t
DEBUG ?= 0
ifneq ($(DEBUG), 0)
CFLAGS += -g -O0
else
CFLAGS += -O2
endif
HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/config.hh $(SRCDIR)/connection.hh $(SRCDIR)/containers.hh $(SRCDIR)/creature.hh $(SRCDIR)/enums.hh $(SRCDIR)/map.hh $(SRCDIR)/monster.hh $(SRCDIR)/objects.hh $(SRCDIR)/player.hh $(SRCDIR)/script.hh $(SRCDIR)/skill.hh $(SRCDIR)/thread.hh
$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/config.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/creature.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/player.obj $(BUILDDIR)/script.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/skill.obj $(BUILDDIR)/thread.obj $(BUILDDIR)/time.obj $(BUILDDIR)/util.obj
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
$(BUILDDIR)/config.obj: $(SRCDIR)/config.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/crcombat.obj: $(SRCDIR)/crcombat.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/creature.obj: $(SRCDIR)/creature.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/main.obj: $(SRCDIR)/main.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/map.obj: $(SRCDIR)/map.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/objects.obj: $(SRCDIR)/objects.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/player.obj: $(SRCDIR)/player.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/script.obj: $(SRCDIR)/script.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/shm.obj: $(SRCDIR)/shm.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/skill.obj: $(SRCDIR)/skill.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/thread.obj: $(SRCDIR)/thread.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/time.obj: $(SRCDIR)/time.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILDDIR)/util.obj: $(SRCDIR)/util.cc $(HEADERS)
@mkdir -p $(@D)
$(CC) -c $(CFLAGS) -o $@ $<
.PHONY: clean
clean:
@rm -r $(BUILDDIR)

View File

@ -11,8 +11,8 @@ set OUTPUTPDB=out.pdb
set INSTALLDIR=..\bin
@REM set SRC="../src/creature.cc" "../src/main.cc" "../src/player.cc" "../src/skill.cc"
set SRC="../src/script.cc" "../src/util.cc"
cl -W3 -WX -Zi -we4244 -we4456 -we4457 -wd4996 -std:c++14 -utf-8 -MP8 -DBUILD_DEBUG=1 -DARCH_X64=1 -D_CRT_SECURE_NO_WARNINGS=1 -Fe:"%OUTPUTEXE%" -Fd:"%OUTPUTPDB%" %* %SRC% /link -subsystem:console -incremental:no -opt:ref -dynamicbase "ws2_32.lib"
set SRC="../src/map.cc" "../src/script.cc" "../src/util.cc"
cl -W3 -WX -Zi -we4244 -we4456 -we4457 -wd4996 -std:c++14 -EHsc -utf-8 -MP8 -DBUILD_DEBUG=1 -DARCH_X64=1 -D_CRT_SECURE_NO_WARNINGS=1 -Fe:"%OUTPUTEXE%" -Fd:"%OUTPUTPDB%" %* %SRC% /link -subsystem:console -incremental:no -opt:ref -dynamicbase "ws2_32.lib"
if errorlevel 1 exit /b errorlevel

View File

@ -186,11 +186,3 @@ enum SITUATION: int {
BUSY=3,
VANISH=4
};
enum BloodType: int {
BT_BLOOD=0,
BT_SLIME=1,
BT_BONES=2,
BT_FIRE=3,
BT_ENERGY=4
};

View File

@ -19,7 +19,7 @@ typedef uintptr_t uintptr;
typedef size_t usize;
#define STATIC_ASSERT(expr) static_assert((expr), "static assertion failed: " #expr)
#define NARRAY(arr) (sizeof(arr) / sizeof(arr[0]))
#define NARRAY(arr) (int)(sizeof(arr) / sizeof(arr[0]))
#define ISPOW2(x) ((x) != 0 && ((x) & ((x) - 1)) == 0)
#define KB(x) ((usize)(x) << 10)
#define MB(x) ((usize)(x) << 20)
@ -80,10 +80,9 @@ STATIC_ASSERT(sizeof(int) == 4);
// be too difficult either. Overall this design is outdated and should be reviewed.
// Nevertheless, we should focus on getting it working as intended, on the target
// platform (which is Linux 32-bits) before attempting to refine it.
//STATIC_ASSERT(OS_LINUX);
//#include <sys/types.h>
typedef int pid_t;
//
STATIC_ASSERT(OS_LINUX);
#include <errno.h>
#include <unistd.h>
// shm.cc
// =============================================================================
@ -120,7 +119,6 @@ void ExitSHMExtern(void);
// =============================================================================
extern uint32 RoundNr;
extern uint32 ServerMilliseconds;
void GetRealTime(int *Hour, int *Minute);
void GetTime(int *Hour, int *Minute);
void GetDate(int *Year, int *Cycle, int *Day);
@ -134,8 +132,8 @@ typedef void TErrorFunction(const char *Text);
typedef void TPrintFunction(int Level, const char *Text);
void SetErrorFunction(TErrorFunction *Function);
void SetPrintFunction(TPrintFunction *Function);
void error(char *Text, ...) ATTR_PRINTF(1, 2);
void print(int Level, char *Text, ...) ATTR_PRINTF(1, 2);
void error(const char *Text, ...) ATTR_PRINTF(1, 2);
void print(int Level, const char *Text, ...) ATTR_PRINTF(2, 3);
bool isSpace(int c);
bool isAlpha(int c);
@ -145,7 +143,7 @@ int toLower(int c);
int toUpper(int c);
char *strLower(char *s);
char *strUpper(char *s);
int stricmp(const char *s1, const char *s2, int Pos);
int stricmp(const char *s1, const char *s2, int Max = INT_MAX);
char *findFirst(char *s, char c);
char *findLast(char *s, char c);
@ -166,8 +164,6 @@ struct TReadBuffer: TReadStream {
// REGULAR FUNCTIONS
// =========================================================================
TReadBuffer(uint8 *Data, int Size);
TReadBuffer(const TWriteBuffer &WriteBuffer)
: TReadBuffer(WriteBuffer.Data, WriteBuffer.Size) {}
// VIRTUAL FUNCTIONS
// =========================================================================
@ -207,7 +203,7 @@ struct TWriteBuffer: TWriteStream {
void writeByte(uint8 Byte) override;
void writeWord(uint16 Word) override;
void writeQuad(uint32 Quad) override;
void writeBytes(uint8 *Buffer, int Count) override;
void writeBytes(const uint8 *Buffer, int Count) override;
// DATA
// =========================================================================
@ -227,7 +223,7 @@ struct TDynamicWriteBuffer: TWriteBuffer {
void writeByte(uint8 Byte) override;
void writeWord(uint16 Word) override;
void writeQuad(uint32 Quad) override;
void writeBytes(uint8 *Buffer, int Count) override;
void writeBytes(const uint8 *Buffer, int Count) override;
// TODO(fusion): Appended virtual functions. These are not in the base class
// VTABLE which can be problematic if we intend to use polymorphism, although

View File

@ -1,4 +1,7 @@
#include "config.hh"
#include "script.hh"
#include "stubs.hh"
char BINPATH[4096];
char DATAPATH[4096];
@ -254,16 +257,16 @@ void ReadConfig(void){
}else if(strcmp(Identifier, "querymanager") == 0){
Script.readSymbol('{');
do{
if(NumberOfQueryManager >= NARRAY(QUERY_MANAGER)){
if(NumberOfQueryManagers >= NARRAY(QUERY_MANAGER)){
Script.error("Cannot handle more query managers");
}
Script.readSymbol('(');
strcpy(QUERY_MANAGER[NumberOfQueryManager].Host, Script.readString());
strcpy(QUERY_MANAGER[NumberOfQueryManagers].Host, Script.readString());
Script.readSymbol(',');
QUERY_MANAGER[NumberOfQueryManager].Port = Script.readNumber();
QUERY_MANAGER[NumberOfQueryManagers].Port = Script.readNumber();
Script.readSymbol(',');
strcpy(QUERY_MANAGER[NumberOfQueryManager].Password, Script.readString());
DisguisePassword(QUERY_MANAGER[NumberOfQueryManager].Password, PasswordKey);
strcpy(QUERY_MANAGER[NumberOfQueryManagers].Password, Script.readString());
DisguisePassword(QUERY_MANAGER[NumberOfQueryManagers].Password, PasswordKey);
Script.readSymbol(')');
NumberOfQueryManagers += 1;
}while(Script.readSpecial() != '}');

View File

@ -75,7 +75,7 @@ struct vector{
increment = this->space;
}
T *entry = new[this->space + increment];
T *entry = new T[this->space + increment];
for(int i = this->min; i <= this->max; i += 1){
int old_index = i - this->start;
int new_index = old_index;
@ -207,7 +207,7 @@ struct priority_queue{
// priority_queue<uint32, uint32> ToDoQueue(5000, 1000);
// priority_queue<uint32, TAttackWave*> AttackWaveQueue(100, 100);
typedef<typename T>
template<typename T>
struct matrix{
// REGULAR FUNCTIONS
// =========================================================================
@ -264,7 +264,7 @@ struct matrix{
T *entry;
};
typedef<typename T>
template<typename T>
struct matrix3d{
// REGULAR FUNCTIONS
// =========================================================================
@ -298,7 +298,7 @@ struct matrix3d{
}
matrix3d(int xmin, int xmax, int ymin, int ymax, int zmin, int zmax, T init)
: matrix(xmin, xmax, ymin, ymax, zmin, zmax) {
: matrix3d(xmin, xmax, ymin, ymax, zmin, zmax) {
int count = this->dx * this->dy * this->dz;
for(int i = 0; i < count; i += 1){
this->entry[i] = init;

View File

@ -10,7 +10,7 @@ TCombat::TCombat(void){
this->ChaseMode = 0;
this->SecureMode = 1;
this->AttackDest = 0;
this->Following;
this->Following = false;
this->Shield = NONE;
this->Close = NONE;
this->Missile = NONE;

View File

@ -1,13 +1,14 @@
#include "creature.hh"
#include "enums.hh"
#include "stubs.hh"
TCreature::TCreature(void) :
TSkillBase(),
Combat(),
ToDoList(0, 20, 10)
{
this->Master = this;
this->Combat.Master = this;
this->ID = 0;
this->NextHashEntry = NULL;
this->NextChainCreature = 0;

View File

@ -4,6 +4,7 @@
#include "common.hh"
#include "connection.hh"
#include "containers.hh"
#include "map.hh"
#include "skill.hh"
struct TCreature;
@ -18,6 +19,7 @@ struct TCombat{
// REGULAR FUNCTIONS
// =========================================================================
TCombat(void);
void CheckCombatValues(void);
// DATA
// =========================================================================
@ -108,7 +110,8 @@ struct TOutfit{
struct TCreature: TSkillBase {
// REGULAR FUNCTIONS
// =========================================================================
// TODO
TCreature(void);
int Damage(TCreature *Attacker, int Damage, int DamageType);
// VIRTUAL FUNCTIONS
// =========================================================================

View File

@ -6,6 +6,14 @@
// TODO(fusion): Probably cleanup these names? Prefix values? Its crazy that
// there are no collision problems (possibly yet).
enum BloodType: int {
BT_BLOOD = 0,
BT_SLIME = 1,
BT_BONES = 2,
BT_FIRE = 3,
BT_ENERGY = 4,
};
enum CreatureType: int {
PLAYER = 0,
MONSTER = 1,

View File

@ -2,8 +2,12 @@
#include "config.hh"
#include "map.hh"
#include "stubs.hh"
#include <signal.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fstream>
static bool BeADaemon = false;
static bool Reboot = false;
@ -62,6 +66,7 @@ static void DefaultHandler(int signr){
SaveMapOn = (signr == SIGQUIT) || (signr == SIGTERM) || (signr == SIGPWR);
if(signr == SIGTERM){
int Hour, Minute;
GetRealTime(&Hour, &Minute);
RebootTime = (Hour * 60 + Minute + 6) % 1440;
CloseGame();
@ -114,7 +119,7 @@ static void SigAlarmHandler(int signr){
SigAlarmCounter += 1;
struct itimerval new_timer = {};
strict itimerval old_timer = {};
struct itimerval old_timer = {};
new_timer.it_value.tv_usec = Beat * 1000;
setitimer(ITIMER_REAL, &new_timer, &old_timer);
}
@ -122,12 +127,12 @@ static void SigAlarmHandler(int signr){
static void InitTime(void){
SigAlarmCounter = 0;
handler(SIGALRM, SigAlarmHandler);
SigAlarmHandler(SIGALARM);
SigAlarmHandler(SIGALRM);
}
static void ExitTime(void){
struct itimerval new_timer = {};
strict itimerval old_timer = {};
struct itimerval old_timer = {};
setitimer(ITIMER_REAL, &new_timer, &old_timer);
handler(SIGALRM, SIG_IGN);
}
@ -138,7 +143,7 @@ static void UnlockGame(void){
strcpy(FileName, SAVEPATH);
strcat(FileName, "/game.pid");
std::ifstream InputFile(Filename, std::ios_base::in);
std::ifstream InputFile(FileName, std::ios_base::in);
if(!InputFile.fail()){
int Pid;
InputFile >> Pid;
@ -156,7 +161,7 @@ static void LockGame(void){
strcat(FileName, "/game.pid");
{
std::ifstream InputFile(Filename, std::ios_base::in);
std::ifstream InputFile(FileName, std::ios_base::in);
if(!InputFile.fail()){
int Pid;
InputFile >> Pid;
@ -200,7 +205,7 @@ void LoadWorldConfig(void){
WorldType = NORMAL;
RebootTime = 6 * 60; // minutes
strcpy(GameAddress, "127.0.0.1"); // I KNOW
Port = 7171;
GamePort = 7171;
MaxPlayers = 1000;
PremiumPlayerBuffer = 100;
MaxNewbies = 200;
@ -292,7 +297,7 @@ static void AdvanceGame(int Delay){
if(CreatureTimeCounter >= 1750){
CreatureTimeCounter -= 1000;
ProcessCreature();
ProcessCreatures();
}
if(CronTimeCounter >= 1500){

1663
src/map.cc

File diff suppressed because it is too large Load Diff

View File

@ -3,12 +3,22 @@
#include "common.hh"
#include "objects.hh"
#include "script.hh"
struct Object {
// REGULAR FUNCTIONS
// =========================================================================
Object(void) { this->ObjectID = 0; }
Object(uint32 ObjectID) { this->ObjectID = ObjectID; }
constexpr Object(void) : ObjectID(0) {}
constexpr Object(uint32 ObjectID): ObjectID(ObjectID) {}
constexpr bool operator==(const Object &other) const {
return this->ObjectID == other.ObjectID;
}
constexpr bool operator!=(const Object &other) const {
return this->ObjectID != other.ObjectID;
}
bool exists(void);
ObjectType getObjectType(void);
@ -71,7 +81,36 @@ struct TCronEntry {
int Next;
};
// NOTE(fusion): Map management functions. Most for internal use.
void SwapObject(TWriteBinaryFile *File, Object Obj, uint32 FileNumber);
void SwapSector(void);
void UnswapSector(uint32 FileNumber);
void DeleteSwappedSectors(void);
void LoadObjects(TReadScriptFile *Script, TWriteStream *Stream, bool Skip);
void LoadObjects(TReadStream *Stream, Object Con);
void InitSector(int SectorX, int SectorY, int SectorZ);
void LoadSector(const char *FileName, int SectorX, int SectorY, int SectorZ);
void LoadMap(void);
void SaveObjects(Object Obj, TWriteStream *Stream, bool Stop);
void SaveObjects(TReadStream *Stream, TWriteScriptFile *Script);
void SaveSector(char *FileName, int SectorX, int SectorY, int SectorZ);
void SaveMap(void);
void InitMap(void);
void ExitMap(bool Save);
// NOTE(fusion): Object related functions.
Object CreateObject(void);
TObject *AccessObject(Object Obj);
void ChangeObject(Object Obj, ObjectType NewType);
int GetObjectPriority(Object Obj);
void PlaceObject(Object Obj, Object Con, bool Append);
Object AppendObject(Object Con, ObjectType Type);
Object GetFirstContainerObject(Object Con);
Object GetContainerObject(Object Con, int Index);
void GetObjectCoordinates(Object Obj, int *x, int *y, int *z);
uint8 GetMapContainerFlags(Object Obj);
Object GetMapContainer(int x, int y, int z);
Object GetMapContainer(Object Obj);
Object GetFirstObject(int x, int y, int z);
#endif //TIBIA_MAP_HH_

View File

@ -85,4 +85,6 @@ struct TMonster: TNonplayer {
};
#endif
extern TRaceData RaceData[512];
#endif //TIBIA_MONSTER_HH_

View File

@ -1,4 +1,5 @@
#include "objects.hh"
#include "containers.hh"
static vector<TObjectType> ObjectTypes(0, 5000, 1000);
static ObjectType SpecialObjects[49];
@ -69,24 +70,24 @@ static FLAG TypeAttributeFlags[62] = {
};
static FLAG InstanceAttributeFlags[18] = {
CONTAINER // CONTENT
CHEST // CHESTQUESTNUMBER
CUMULATIVE // AMOUNT
KEY // KEYNUMBER
KEYDOOR // KEYHOLENUMBER
LEVELDOOR // DOORLEVEL
QUESTDOOR // DOORQUESTNUMBER
QUESTDOOR // DOORQUESTVALUE
RUNE // CHARGES
TEXT // TEXTSTRING
TEXT // EDITOR
LIQUIDCONTAINER // CONTAINERLIQUIDTYPE
LIQUIDPOOL // POOLLIQUIDTYPE
TELEPORTABSOLUTE // ABSTELEPORTDESTINATION
MAGICFIELD // RESPONSIBLE
EXPIRE // REMAININGEXPIRETIME
EXPIRESTOP // SAVEDEXPIRETIME
WEAROUT // REMAININGUSES
CONTAINER, // CONTENT
CHEST, // CHESTQUESTNUMBER
CUMULATIVE, // AMOUNT
KEY, // KEYNUMBER
KEYDOOR, // KEYHOLENUMBER
LEVELDOOR, // DOORLEVEL
QUESTDOOR, // DOORQUESTNUMBER
QUESTDOOR, // DOORQUESTVALUE
RUNE, // CHARGES
TEXT, // TEXTSTRING
TEXT, // EDITOR
LIQUIDCONTAINER, // CONTAINERLIQUIDTYPE
LIQUIDPOOL, // POOLLIQUIDTYPE
TELEPORTABSOLUTE, // ABSTELEPORTDESTINATION
MAGICFIELD, // RESPONSIBLE
EXPIRE, // REMAININGEXPIRETIME
EXPIRESTOP, // SAVEDEXPIRETIME
WEAROUT, // REMAININGUSES
};
static const char InstanceAttributeNames[18][30] = {
@ -180,6 +181,11 @@ const char *ObjectType::getDescription(void){
// Object Type Related Functions
// =============================================================================
const char *GetInstanceAttributeName(int Attribute){
ASSERT(Attribute >= 0 && Attribute <= 17);
return InstanceAttributeNames[Attribute];
}
int GetInstanceAttributeByName(const char *Name){
int Result = -1;
for(int i = 0; i < NARRAY(InstanceAttributeNames); i += 1){

View File

@ -65,6 +65,7 @@ struct TObjectType {
int AttributeOffsets[18];
};
const char *GetInstanceAttributeName(int Attribute);
int GetInstanceAttributeByName(const char *Name);
bool ObjectTypeExists(int TypeID);
//void InitObjects(void);

View File

@ -1,6 +1,8 @@
#include "player.hh"
#include "enums.hh"
#include "stubs.hh"
void TPlayer::CheckState(void){
if(this->Connection != NULL){
uint8 State = 0;

View File

@ -69,6 +69,7 @@ struct TPlayer: TCreature {
// REGULAR FUNCTIONS
// =========================================================================
void CheckState(void);
uint8 GetActiveProfession(void);
// VIRTUAL FUNCTIONS
// =========================================================================

View File

@ -595,7 +595,7 @@ TWriteScriptFile::~TWriteScriptFile(void){
}
}
void TWriteScriptFile::open(char *FileName){
void TWriteScriptFile::open(const char *FileName){
if(this->File != NULL){
::error("TWriteScriptFile::open: Altes Skript ist noch offen.\n");
if(fclose(this->File) != 0){
@ -628,7 +628,7 @@ void TWriteScriptFile::close(void){
this->File = NULL;
}
void TWriteScriptFile::error(char *Text){
void TWriteScriptFile::error(const char *Text){
if(this->File != NULL){
if(fclose(this->File) != 0){
::error("TWriteScriptFile::error: Fehler %d beim Schließen der Datei.\n", errno);
@ -638,7 +638,7 @@ void TWriteScriptFile::error(char *Text){
snprintf(ErrorString, sizeof(ErrorString),
"error in script-file \"%s\", line %d: %s",
this->Filename, this->Line);
this->Filename, this->Line, Text);
throw ErrorString;
}
@ -652,7 +652,7 @@ void TWriteScriptFile::writeLn(void){
putc('\n', this->File);
}
void TWriteScriptFile::writeText(char *Text){
void TWriteScriptFile::writeText(const char *Text){
if(this->File == NULL){
::error("TWriteScriptFile::writeText: Kein Skript zum Schreiben geöffnet.\n");
throw "Cannot write text";
@ -679,9 +679,9 @@ void TWriteScriptFile::writeNumber(int Number){
this->writeText(s);
}
void TWriteScriptFile::writeString(char *Text){
void TWriteScriptFile::writeString(const char *Text){
if(this->File == NULL){
::error();
::error("TWriteScriptFile::writeString: Kein Skript zum Schreiben geöffnet.\n");
throw "Cannot write string";
}
@ -722,7 +722,7 @@ void TWriteScriptFile::writeCoordinate(int x ,int y ,int z){
this->writeText(s);
}
void TWriteScriptFile::writeBytesequence(uint8 *Sequence, int Length){
void TWriteScriptFile::writeBytesequence(const uint8 *Sequence, int Length){
if(this->File == NULL){
::error("TWriteScriptFile::writeBytesequence: Kein Skript zum Schreiben geöffnet.\n");
throw "Cannot write bytesequence";
@ -743,6 +743,7 @@ void TWriteScriptFile::writeBytesequence(uint8 *Sequence, int Length){
putc('-', this->File);
}
char s[32];
snprintf(s, sizeof(s), "%u", Sequence[i]);
this->writeText(s);
}
@ -754,7 +755,7 @@ TReadBinaryFile::TReadBinaryFile(void){
this->File = NULL;
}
void TReadBinaryFile::open(char *FileName){
void TReadBinaryFile::open(const char *FileName){
if(this->File != NULL){
this->error("File still open");
}
@ -770,7 +771,7 @@ void TReadBinaryFile::open(char *FileName){
this->FileSize = -1;
}
int TReadBinaryFile::close(void){
void TReadBinaryFile::close(void){
// TODO(fusion): Check if file is NULL?
if(fclose(this->File) != 0){
int ErrCode = errno;
@ -781,7 +782,7 @@ int TReadBinaryFile::close(void){
this->File = NULL;
}
void TReadBinaryFile::error(char *Text){
void TReadBinaryFile::error(const char *Text){
if(this->File != NULL){
if(fclose(this->File) != 0){
::error("TReadBinaryFile::error: Fehler %d beim Schließen der Datei.\n", errno);
@ -870,7 +871,7 @@ void TReadBinaryFile::readBytes(uint8 *Buffer, int Count){
}
}
bool TReadBinaryFile::eof(TReadBinaryFile *this){
bool TReadBinaryFile::eof(void){
if(this->File == NULL){
this->error("File not open for eof check");
}
@ -901,7 +902,7 @@ TWriteBinaryFile::TWriteBinaryFile(void){
this->File = NULL;
}
void TWriteBinaryFile::open(char *FileName){
void TWriteBinaryFile::open(const char *FileName){
if(this->File != NULL){
this->error("File still open");
}
@ -932,7 +933,7 @@ void TWriteBinaryFile::close(void){
this->File = NULL;
}
void TWriteBinaryFile::error(char *Text){
void TWriteBinaryFile::error(const char *Text){
if(this->File != NULL){
if(fclose(this->File) != 0){
::error("TWriteBinaryFile::error: Fehler %d beim Schließen der Datei.\n", errno);
@ -966,7 +967,7 @@ void TWriteBinaryFile::writeByte(uint8 Byte){
}
}
void TWriteBinaryFile::writeBytes(uint8 *Buffer, int Count){
void TWriteBinaryFile::writeBytes(const uint8 *Buffer, int Count){
int Result = (int)fwrite(Buffer, 1, Count, this->File);
if(Result != Count){
int ErrCode = errno;

View File

@ -86,15 +86,15 @@ struct TWriteScriptFile {
// =========================================================================
TWriteScriptFile(void);
~TWriteScriptFile(void);
void open(char *FileName);
void open(const char *FileName);
void close(void);
void error(char *Text);
void error(const char *Text);
void writeLn(void);
void writeText(char *Text);
void writeText(const char *Text);
void writeNumber(int Number);
void writeString(char *Text);
void writeString(const char *Text);
void writeCoordinate(int x ,int y ,int z);
void writeBytesequence(uint8 *Sequence, int Length);
void writeBytesequence(const uint8 *Sequence, int Length);
// DATA
// =========================================================================
@ -107,9 +107,9 @@ struct TReadBinaryFile: TReadStream {
// REGULAR FUNCTIONS
// =========================================================================
TReadBinaryFile(void);
void open(char *FileName);
int close(void);
void error(char *Text);
void open(const char *FileName);
void close(void);
void error(const char *Text);
int getPosition(void);
int getSize(void);
void seek(int Offset);
@ -118,13 +118,13 @@ struct TReadBinaryFile: TReadStream {
// =========================================================================
uint8 readByte(void) override;
void readBytes(uint8 *Buffer, int Count) override;
bool eof(TReadBinaryFile *this) override;
bool eof(void) override;
void skip(int Count) override;
// TODO(fusion): Appended virtual functions. These are not in the base class
// VTABLE which can be problematic if we intend to use polymorphism, although
// that doesn't seem to be case.
virtual ~TReadBinaryFile(void) override; // VTABLE[8]
virtual ~TReadBinaryFile(void); // VTABLE[8]
// Duplicate destructor that also calls operator delete. // VTABLE[9]
// DATA
@ -138,14 +138,14 @@ struct TWriteBinaryFile: TWriteStream {
// REGULAR FUNCTIONS
// =========================================================================
TWriteBinaryFile(void);
void open(char *FileName);
void open(const char *FileName);
void close(void);
void error(char *Text);
void error(const char *Text);
// VIRTUAL FUNCTIONS
// =========================================================================
void writeByte(uint8 Byte) override;
void writeBytes(uint8 *Buffer, int Count) override;
void writeBytes(const uint8 *Buffer, int Count) override;
// TODO(fusion): Appended virtual functions. These are not in the base class
// VTABLE which can be problematic if we intend to use polymorphism, although

View File

@ -1,4 +1,11 @@
#include "common.hh"
#include "config.hh"
#include "enums.hh"
#include "thread.hh"
#include "stubs.hh"
#include <sys/shm.h>
// NOTE(fusion): This looks like an interface to external tools. Looking at the
// `bin` directory this program was in, there are other programs that probably
@ -103,7 +110,7 @@ pid_t GetGameThreadPID(void){
return Pid;
}
static void ErrorHandler(char *Text){
static void ErrorHandler(const char *Text){
if(VerboseOutput){
printf("%s", Text);
}
@ -119,7 +126,7 @@ static void ErrorHandler(char *Text){
}
}
static void PrintHandler(int Level, char *Text){
static void PrintHandler(int Level, const char *Text){
static Semaphore LogfileMutex(1);
if(Level > DebugLevel){
@ -249,7 +256,7 @@ void SetCommand(int Command, char *Text){
if(Text == NULL){
SHM->CommandBuffer[0] = 0;
}else{
strncpy(SHM->CommandBuffer, sizeof(SHM->CommandBuffer), Text);
strncpy(SHM->CommandBuffer, Text, sizeof(SHM->CommandBuffer));
SHM->CommandBuffer[sizeof(SHM->CommandBuffer) - 1] = 0;
}
}
@ -359,8 +366,9 @@ void InitSHM(bool Verbose){
// the decompiled version was also clearing SHM, probably just in case.
memset(SHM, 0, sizeof(TSharedMemory));
strncpy(SHM->PrintBuffer[0], sizeof(SHM->PrintBuffer[0]),
"SHM initialized. System printing is working!\n");
strncpy(SHM->PrintBuffer[0],
"SHM initialized. System printing is working!\n",
sizeof(SHM->PrintBuffer[0]));
SHM->PrintBuffer[0][sizeof(SHM->PrintBuffer[0]) - 1] = 0;
SHM->PrintBufferPosition = 1;

View File

@ -1,8 +1,11 @@
#include "skill.hh"
#include "enums.hh"
#include "creature.hh"
#include "monster.hh"
#include "player.hh"
#include "stubs.hh"
#include <math.h>
// TSkill REGULAR FUNCTIONS
@ -952,8 +955,7 @@ void TSkillIllusion::Event(int Range){
if(this->Get() <= 0){
Master->Outfit = Master->OrgOutfit;
AnnounceChangedCreature(Master->ID, 3);
// TODO(fusion): I'm not sure this is correct.
NotifyAllCreatures(&Master->CrObject, 2, &NONE);
NotifyAllCreatures(Master->CrObject, 2, NONE);
}
}
}
@ -1101,7 +1103,7 @@ void TSkillEnergy::Event(int Range){
// TSkillBase
//==============================================================================
TSkillBase::TSkillBase(void){
STATIC_ASSERT(NARRAY(this>Skills) == NARRAY(this->TimerList));
STATIC_ASSERT(NARRAY(this->Skills) == NARRAY(this->TimerList));
for(int i = 0; i < NARRAY(this->Skills); i += 1){
this->Skills[i] = NULL;
this->TimerList[i] = NULL;

64
src/stubs.hh Normal file
View File

@ -0,0 +1,64 @@
#ifndef TIBIA_STUBS_HH_
#define TIBIA_STUBS_HH_ 1
#include "common.hh"
#include "enums.hh"
#include "connection.hh"
#include "creature.hh"
#include "map.hh"
#include "player.hh"
// IMPORTANT(fusion): These function definitions exist to test compilation. They're
// not yet implemented and will cause the linker to fail with unresolved symbols.
typedef void TRefreshSectorFunction(int SectorX, int SectorY, int SectorZ, TReadStream *Stream);
typedef void TSendMailsFunction(TPlayerData *PlayerData);
extern void AbortWriter(void);
extern uint32 AddDynamicString(const char *Text);
extern void AnnounceChangedCreature(uint32 CreatureID, int Type);
extern void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3);
extern bool CheckRight(uint32 CreatureID, RIGHT Right);
extern void CleanupDynamicStrings(void);
extern void CreatePlayerList(bool Online);
extern void CronChange(Object Obj, int NewDelay);
extern void CronExpire(Object Obj, int Delay);
extern uint32 CronInfo(Object Obj, bool Delete);
extern uint32 CronStop(Object Obj);
extern void DeleteDynamicString(uint32 Number);
extern bool FileExists(const char *FileName);
extern TCreature *GetCreature(uint32 CreatureID);
extern const char *GetDynamicString(uint32 Number);
extern TConnection *GetFirstConnection(void);
extern TConnection *GetNextConnection(void);
extern bool IsProtectionZone(int x, int y, int z);
extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3);
extern void LogoutAllPlayers(void);
extern void MoveCreatures(int Delay);
extern void NetLoadCheck(void);
extern void NetLoadSummary(void);
extern void NotifyAllCreatures(Object Obj, int Type, Object OldCon);
extern void ProcessCommunicationControl(void);
extern void ProcessConnections(void);
extern void ProcessCreatures(void);
extern void ProcessCronSystem(void);
extern void ProcessMonsterhomes(void);
extern void ProcessMonsterRaids(void);
extern void ProcessReaderThreadReplies(TRefreshSectorFunction *RefreshSector, TSendMailsFunction *SendMails);
extern void ProcessSkills(void);
extern void ProcessWriterThreadReplies(void);
extern void ReceiveData(void);
extern void RefreshCylinders(void);
extern void RefreshMap(void);
extern void RefreshSector(int SectorX, int SectorY, int SectorZ, TReadStream *Stream);
extern void SavePlayerDataOrder(void);
extern void SendAll(void);
extern void SendAmbiente(TConnection *Connection);
extern void SendMails(TPlayerData *PlayerData);
extern void SendMessage(TConnection *Connection, int Mode, const char *Text, ...) ATTR_PRINTF(3, 4);
extern void SendPlayerData(TConnection *Connection);
extern void SendPlayerSkills(TConnection *Connection);
extern void SendPlayerState(TConnection *Connection, uint8 State);
extern void WriteKillStatistics(void);
#endif //TIBIA_STUBS_HH_

View File

@ -50,7 +50,7 @@ int JoinThread(ThreadHandle Handle){
int Result = 0;
int *ResultPointer;
pthread_join((pthread_t)Handle, &ResultPointer);
pthread_join((pthread_t)Handle, (void**)&ResultPointer);
if(ResultPointer != NULL){
Result = *ResultPointer;
delete ResultPointer;

View File

@ -18,7 +18,7 @@ void DelayThread(int Seconds, int MicroSeconds);
struct Semaphore {
// REGULAR FUNCTIONS
// =========================================================================
Semaphore(void);
Semaphore(int Value);
~Semaphore(void);
void up(void);
void down(void);

View File

@ -1,5 +1,7 @@
#include "common.hh"
#include <time.h>
// IMPORTANT(fusion): `RoundNr` is just the number of seconds since startup which
// is why `GetRoundAtTime` and `GetRoundForNextMinute` straight up uses it as
// seconds. It is incremented every 1 second inside `AdvanceGame`.
@ -38,7 +40,7 @@ void GetDate(int *Year, int *Cycle, int *Day){
// NOTE(fusion): This maps each real time week to a game time year.
time_t RealTime = time(NULL);
struct tm LocalTime = GetLocalTimeTM(RealTime);
*Year = ((T / 86400) + 4) / 7
*Year = (int)(((RealTime / 86400) + 4) / 7);
*Cycle = LocalTime.tm_wday;
*Day = LocalTime.tm_hour;
}
@ -79,7 +81,7 @@ void GetAmbiente(int *Brightness, int *Color){
}
uint32 GetRoundAtTime(int Hour, int Minute){
struct tm LocalTime = GetLocalTimeTM(RealTime);
struct tm LocalTime = GetLocalTimeTM(time(NULL));
int SecondsToTime = (Hour - LocalTime.tm_hour) * 3600
+ (Minute - LocalTime.tm_min) * 60
+ (0 - LocalTime.tm_sec);
@ -90,7 +92,7 @@ uint32 GetRoundAtTime(int Hour, int Minute){
}
uint32 GetRoundForNextMinute(void){
struct tm LocalTime = GetLocalTimeTM(RealTime);
struct tm LocalTime = GetLocalTimeTM(time(NULL));
int SecondsToNextMinute = 60 - LocalTime.tm_sec;
return SecondsToNextMinute + RoundNr + 30;
}

View File

@ -11,7 +11,7 @@ void SetPrintFunction(TPrintFunction *Function){
PrintFunction = Function;
}
void error(char *Text, ...){
void error(const char *Text, ...){
char s[1024];
va_list ap;
@ -26,7 +26,7 @@ void error(char *Text, ...){
}
}
void print(int Level, char *Text, ...){
void print(int Level, const char *Text, ...){
char s[1024];
va_list ap;
@ -109,8 +109,8 @@ char *strUpper(char *s){
return s;
}
int stricmp(const char *s1, const char *s2, int Pos){
for(int i = 0; i < Pos; i += 1){
int stricmp(const char *s1, const char *s2, int Max /*= INT_MAX*/){
for(int i = 0; i < Max; i += 1){
int c1 = toLower(s1[i]);
int c2 = toLower(s2[i]);
if(c1 > c2){
@ -120,11 +120,12 @@ int stricmp(const char *s1, const char *s2, int Pos){
}else{
ASSERT(c1 == c2);
if(c1 == 0){
break;
}
}
}
return 0;
}
}
}
}
char *findFirst(char *s, char c){
return strchr(s, (int)c);
@ -179,7 +180,7 @@ void TReadStream::readString(char *Buffer, int MaxLength){
if(Length > 0){
if(MaxLength < 0 || MaxLength > Length){
this->readBytes(Buffer, Length);
this->readBytes((uint8*)Buffer, Length);
Buffer[Length] = 0;
}else{
this->readBytes((uint8*)Buffer, MaxLength - 1);
@ -375,7 +376,7 @@ void TWriteBuffer::writeQuad(uint32 Quad){
this->Position += 4;
}
void TWriteBuffer::writeBytes(uint8 *Buffer, int Count){
void TWriteBuffer::writeBytes(const uint8 *Buffer, int Count){
if((this->Size - this->Position) < Count){
throw "buffer full";
}
@ -436,7 +437,7 @@ void TDynamicWriteBuffer::writeQuad(uint32 Quad){
this->Position += 4;
}
void TDynamicWriteBuffer::writeBytes(uint8 *Buffer, int Count){
void TDynamicWriteBuffer::writeBytes(const uint8 *Buffer, int Count){
while((this->Size - this->Position) < Count){
this->resizeBuffer();
}