2 Commits

Author SHA1 Message Date
CakeLancelot
ab480d88f1 Update version numbers to 1.5 2023-10-07 18:20:04 -05:00
CakeLancelot
89772d763b CI: specify Ubuntu runner version and fix artifact zip name
We were technically already using 22.04 for a bit, it got updated without us noticing since the version was set to `ubuntu-latest`.
Affix the version to 22.04 so that it doesn't get unexpectedly updated again, and update the artifact's zip to reflect the change.
2023-10-07 17:13:13 -05:00
29 changed files with 73 additions and 74 deletions

View File

@@ -53,7 +53,7 @@ jobs:
- name: Upload build artifact - name: Upload build artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: 'ubuntu20_04-bin-x64-${{ env.SHORT_SHA }}' name: 'ubuntu22_04-bin-x64-${{ env.SHORT_SHA }}'
path: bin path: bin
windows-build: windows-build:
@@ -112,7 +112,7 @@ jobs:
copy-artifacts: copy-artifacts:
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/master' if: github.event_name != 'pull_request' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest runs-on: ubuntu-22.04
needs: [windows-build, ubuntu-build] needs: [windows-build, ubuntu-build]
env: env:
BOT_SSH_KEY: ${{ secrets.BOT_SSH_KEY }} BOT_SSH_KEY: ${{ secrets.BOT_SSH_KEY }}

View File

@@ -13,13 +13,13 @@ OpenFusion is a reverse-engineered server for FusionFall. It primarily targets v
### Getting Started ### Getting Started
#### Method A: Installer (Easiest) #### Method A: Installer (Easiest)
1. Download the client installer by clicking [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.4/OpenFusionClient-1.4-Installer.exe) - choose to run the file. 1. Download the client installer by clicking [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.5/OpenFusionClient-1.5-Installer.exe) - choose to run the file.
2. After a few moments, the client should open: you will be given a choice between two public servers by default. Select the one you wish to play and click connect. 2. After a few moments, the client should open: you will be given a choice between two public servers by default. Select the one you wish to play and click connect.
3. To create an account, simply enter the details you wish to use at the login screen then click Log In. Do *not* click register, as this will just lead to a blank screen. 3. To create an account, simply enter the details you wish to use at the login screen then click Log In. Do *not* click register, as this will just lead to a blank screen.
4. Make a new character, and enjoy the game! Your progress will be saved automatically, and you can resume playing by entering the login details you used in step 3. 4. Make a new character, and enjoy the game! Your progress will be saved automatically, and you can resume playing by entering the login details you used in step 3.
#### Method B: Standalone .zip file #### Method B: Standalone .zip file
1. Download the client from [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.4/OpenFusionClient-1.4.zip). 1. Download the client from [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.5/OpenFusionClient-1.5.zip).
2. Extract it to a folder of your choice. Note: if you are upgrading from an older version, it is preferable to start with a fresh folder rather than overwriting a previous install. 2. Extract it to a folder of your choice. Note: if you are upgrading from an older version, it is preferable to start with a fresh folder rather than overwriting a previous install.
3. Run OpenFusionClient.exe - you will be given a choice between two public servers by default. Select the one you wish to play and click connect. 3. Run OpenFusionClient.exe - you will be given a choice between two public servers by default. Select the one you wish to play and click connect.
4. To create an account, simply enter the details you wish to use at the login screen then click Log In. Do *not* click register, as this will just lead to a blank screen. 4. To create an account, simply enter the details you wish to use at the login screen then click Log In. Do *not* click register, as this will just lead to a blank screen.
@@ -29,7 +29,7 @@ Instructions for getting the client to run on Linux through Wine can be found [h
### Hosting a server ### Hosting a server
1. Grab `OpenFusionServer-1.4-original.zip` or `OpenFusionServer-1.4-academy.zip` from [here](https://github.com/OpenFusionProject/OpenFusion/releases/tag/1.4). 1. Grab `OpenFusionServer-1.5-original.zip` or `OpenFusionServer-1.5-academy.zip` from [here](https://github.com/OpenFusionProject/OpenFusion/releases/tag/1.5).
2. Extract it to a folder of your choice, then run `winfusion.exe` (Windows) or `fusion` (Linux) to start the server. 2. Extract it to a folder of your choice, then run `winfusion.exe` (Windows) or `fusion` (Linux) to start the server.
3. Add a new server to the client's list: 3. Add a new server to the client's list:
1. For Description, enter anything you want. This is what will show up in the server list. 1. For Description, enter anything you want. This is what will show up in the server list.

View File

@@ -546,7 +546,7 @@ bool doDamageNDebuff(Mob *mob, sSkillResult_Damage_N_Debuff *respdata, int i, in
respdata[i].bProtected = 0; respdata[i].bProtected = 0;
std::pair<CNSocket*, int32_t> key = std::make_pair(sock, bitFlag); std::pair<CNSocket*, int32_t> key = std::make_pair(sock, bitFlag);
int64_t until = getTime() + (int64_t)duration * 100; time_t until = getTime() + (time_t)duration * 100;
Eggs::EggBuffs[key] = until; Eggs::EggBuffs[key] = until;
} }
respdata[i].iConditionBitFlag = plr->iConditionBitFlag; respdata[i].iConditionBitFlag = plr->iConditionBitFlag;

View File

@@ -58,7 +58,7 @@ static std::pair<int,int> getDamage(int attackPower, int defensePower, bool shou
static bool checkRapidFire(CNSocket *sock, int targetCount) { static bool checkRapidFire(CNSocket *sock, int targetCount) {
Player *plr = PlayerManager::getPlayer(sock); Player *plr = PlayerManager::getPlayer(sock);
int64_t currTime = getTime(); time_t currTime = getTime();
if (currTime - plr->lastShot < plr->fireRate * 80) if (currTime - plr->lastShot < plr->fireRate * 80)
plr->suspicionRating += plr->fireRate * 100 + plr->lastShot - currTime; // gain suspicion for rapid firing plr->suspicionRating += plr->fireRate * 100 + plr->lastShot - currTime; // gain suspicion for rapid firing
@@ -158,7 +158,7 @@ static void pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
PlayerManager::sendToViewable(sock, respbuf, P_FE2CL_PC_ATTACK_NPCs); PlayerManager::sendToViewable(sock, respbuf, P_FE2CL_PC_ATTACK_NPCs);
} }
void Combat::npcAttackPc(Mob *mob, int64_t currTime) { void Combat::npcAttackPc(Mob *mob, time_t currTime) {
Player *plr = PlayerManager::getPlayer(mob->target); Player *plr = PlayerManager::getPlayer(mob->target);
INITVARPACKET(respbuf, sP_FE2CL_NPC_ATTACK_PCs, pkt, sAttackResult, atk); INITVARPACKET(respbuf, sP_FE2CL_NPC_ATTACK_PCs, pkt, sAttackResult, atk);
@@ -654,7 +654,7 @@ static void projectileHit(CNSocket* sock, CNPacketData* data) {
} }
// rapid fire anti-cheat // rapid fire anti-cheat
int64_t currTime = getTime(); time_t currTime = getTime();
if (currTime - plr->lastShot < plr->fireRate * 80) if (currTime - plr->lastShot < plr->fireRate * 80)
plr->suspicionRating += plr->fireRate * 100 + plr->lastShot - currTime; // gain suspicion for rapid firing plr->suspicionRating += plr->fireRate * 100 + plr->lastShot - currTime; // gain suspicion for rapid firing
else if (currTime - plr->lastShot < plr->fireRate * 180 && plr->suspicionRating > 0) else if (currTime - plr->lastShot < plr->fireRate * 180 && plr->suspicionRating > 0)
@@ -726,8 +726,8 @@ static void projectileHit(CNSocket* sock, CNPacketData* data) {
Bullets[plr->iID].erase(resp->iBulletID); Bullets[plr->iID].erase(resp->iBulletID);
} }
static void playerTick(CNServer *serv, int64_t currTime) { static void playerTick(CNServer *serv, time_t currTime) {
static int64_t lastHealTime = 0; static time_t lastHealTime = 0;
for (auto& pair : PlayerManager::players) { for (auto& pair : PlayerManager::players) {
CNSocket *sock = pair.first; CNSocket *sock = pair.first;

View File

@@ -23,7 +23,7 @@ namespace Combat {
void init(); void init();
void npcAttackPc(Mob *mob, int64_t currTime); void npcAttackPc(Mob *mob, time_t currTime);
int hitMob(CNSocket *sock, Mob *mob, int damage); int hitMob(CNSocket *sock, Mob *mob, int damage);
void killMob(CNSocket *sock, Mob *mob); void killMob(CNSocket *sock, Mob *mob);
} }

View File

@@ -11,7 +11,7 @@
using namespace Eggs; using namespace Eggs;
/// sock, CBFlag -> until /// sock, CBFlag -> until
std::map<std::pair<CNSocket*, int32_t>, int64_t> Eggs::EggBuffs; std::map<std::pair<CNSocket*, int32_t>, time_t> Eggs::EggBuffs;
std::unordered_map<int, EggType> Eggs::EggTypes; std::unordered_map<int, EggType> Eggs::EggTypes;
int Eggs::eggBuffPlayer(CNSocket* sock, int skillId, int eggId, int duration) { int Eggs::eggBuffPlayer(CNSocket* sock, int skillId, int eggId, int duration) {
@@ -79,15 +79,15 @@ int Eggs::eggBuffPlayer(CNSocket* sock, int skillId, int eggId, int duration) {
// save the buff serverside; // save the buff serverside;
// if you get the same buff again, new duration will override the previous one // if you get the same buff again, new duration will override the previous one
int64_t until = getTime() + (int64_t)duration * 1000; time_t until = getTime() + (time_t)duration * 1000;
EggBuffs[key] = until; EggBuffs[key] = until;
return 0; return 0;
} }
static void eggStep(CNServer* serv, int64_t currTime) { static void eggStep(CNServer* serv, time_t currTime) {
// tick buffs // tick buffs
int64_t timeStamp = currTime; time_t timeStamp = currTime;
auto it = EggBuffs.begin(); auto it = EggBuffs.begin();
while (it != EggBuffs.end()) { while (it != EggBuffs.end()) {
// check remaining time // check remaining time
@@ -254,7 +254,7 @@ static void eggPickup(CNSocket* sock, CNPacketData* data) {
else { else {
Chunking::removeEntityFromChunks(Chunking::getViewableChunks(egg->chunkPos), eggRef); Chunking::removeEntityFromChunks(Chunking::getViewableChunks(egg->chunkPos), eggRef);
egg->dead = true; egg->dead = true;
egg->deadUntil = getTime() + (int64_t)type->regen * 1000; egg->deadUntil = getTime() + (time_t)type->regen * 1000;
egg->appearanceData.iHP = 0; egg->appearanceData.iHP = 0;
} }
} }

View File

@@ -11,7 +11,7 @@ struct EggType {
}; };
namespace Eggs { namespace Eggs {
extern std::map<std::pair<CNSocket*, int32_t>, int64_t> EggBuffs; extern std::map<std::pair<CNSocket*, int32_t>, time_t> EggBuffs;
extern std::unordered_map<int, EggType> EggTypes; extern std::unordered_map<int, EggType> EggTypes;
void init(); void init();

View File

@@ -103,14 +103,14 @@ struct CombatNPC : public BaseNPC {
int level = 0; int level = 0;
int speed = 300; int speed = 300;
void (*_stepAI)(CombatNPC*, int64_t) = nullptr; void (*_stepAI)(CombatNPC*, time_t) = nullptr;
// XXX // XXX
CombatNPC(int x, int y, int z, int angle, uint64_t iID, int t, int id, int maxHP) : CombatNPC(int x, int y, int z, int angle, uint64_t iID, int t, int id, int maxHP) :
BaseNPC(x, y, z, angle, iID, t, id), BaseNPC(x, y, z, angle, iID, t, id),
maxHealth(maxHP) {} maxHealth(maxHP) {}
virtual void stepAI(int64_t currTime) { virtual void stepAI(time_t currTime) {
if (_stepAI != nullptr) if (_stepAI != nullptr)
_stepAI(this, currTime); _stepAI(this, currTime);
} }
@@ -124,7 +124,7 @@ struct CombatNPC : public BaseNPC {
struct Egg : public BaseNPC { struct Egg : public BaseNPC {
bool summoned = false; bool summoned = false;
bool dead = false; bool dead = false;
int64_t deadUntil; time_t deadUntil;
Egg(int x, int y, int z, uint64_t iID, int t, int32_t id, bool summon) Egg(int x, int y, int z, uint64_t iID, int t, int32_t id, bool summon)
: BaseNPC(x, y, z, 0, iID, t, id) { : BaseNPC(x, y, z, 0, iID, t, id) {

View File

@@ -501,7 +501,7 @@ static void itemUseHandler(CNSocket* sock, CNPacketData* data) {
player->Inven[resp->iSlotNum] = resp->RemainItem; player->Inven[resp->iSlotNum] = resp->RemainItem;
std::pair<CNSocket*, int32_t> key = std::make_pair(sock, value1); std::pair<CNSocket*, int32_t> key = std::make_pair(sock, value1);
int64_t until = getTime() + (int64_t)Nanos::SkillTable[144].durationTime[0] * 100; time_t until = getTime() + (time_t)Nanos::SkillTable[144].durationTime[0] * 100;
Eggs::EggBuffs[key] = until; Eggs::EggBuffs[key] = until;
} }

View File

@@ -14,7 +14,7 @@ using namespace MobAI;
bool MobAI::simulateMobs = settings::SIMULATEMOBS; bool MobAI::simulateMobs = settings::SIMULATEMOBS;
static void roamingStep(Mob *mob, int64_t currTime); static void roamingStep(Mob *mob, time_t currTime);
/* /*
* Dynamic lerp; distinct from Transport::lerp(). This one doesn't care about height and * Dynamic lerp; distinct from Transport::lerp(). This one doesn't care about height and
@@ -119,7 +119,7 @@ void MobAI::groupRetreat(Mob *mob) {
* Even if they're in range, we can't assume they're all in the same one chunk * Even if they're in range, we can't assume they're all in the same one chunk
* as the mob, since it might be near a chunk boundary. * as the mob, since it might be near a chunk boundary.
*/ */
bool MobAI::aggroCheck(Mob *mob, int64_t currTime) { bool MobAI::aggroCheck(Mob *mob, time_t currTime) {
CNSocket *closest = nullptr; CNSocket *closest = nullptr;
int closestDistance = INT_MAX; int closestDistance = INT_MAX;
@@ -281,7 +281,7 @@ static void dealCorruption(Mob *mob, std::vector<int> targetData, int skillID, i
NPCManager::sendToViewable(mob, (void*)&respbuf, P_FE2CL_NPC_SKILL_CORRUPTION_HIT, resplen); NPCManager::sendToViewable(mob, (void*)&respbuf, P_FE2CL_NPC_SKILL_CORRUPTION_HIT, resplen);
} }
static void useAbilities(Mob *mob, int64_t currTime) { static void useAbilities(Mob *mob, time_t currTime) {
/* /*
* targetData approach * targetData approach
* first integer is the count * first integer is the count
@@ -441,7 +441,7 @@ static void drainMobHP(Mob *mob, int amount) {
Combat::killMob(mob->target, mob); Combat::killMob(mob->target, mob);
} }
static void deadStep(Mob *mob, int64_t currTime) { static void deadStep(Mob *mob, time_t currTime) {
// despawn the mob after a short delay // despawn the mob after a short delay
if (mob->killedTime != 0 && !mob->despawned && currTime - mob->killedTime > 2000) { if (mob->killedTime != 0 && !mob->despawned && currTime - mob->killedTime > 2000) {
mob->despawned = true; mob->despawned = true;
@@ -500,7 +500,7 @@ static void deadStep(Mob *mob, int64_t currTime) {
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_NEW, sizeof(sP_FE2CL_NPC_NEW)); NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_NEW, sizeof(sP_FE2CL_NPC_NEW));
} }
static void combatStep(Mob *mob, int64_t currTime) { static void combatStep(Mob *mob, time_t currTime) {
assert(mob->target != nullptr); assert(mob->target != nullptr);
// lose aggro if the player lost connection // lose aggro if the player lost connection
@@ -542,7 +542,7 @@ static void combatStep(Mob *mob, int64_t currTime) {
return; return;
// unbuffing // unbuffing
std::unordered_map<int32_t, int64_t>::iterator it = mob->unbuffTimes.begin(); std::unordered_map<int32_t, time_t>::iterator it = mob->unbuffTimes.begin();
while (it != mob->unbuffTimes.end()) { while (it != mob->unbuffTimes.end()) {
if (currTime >= it->second) { if (currTime >= it->second) {
@@ -640,7 +640,7 @@ static void combatStep(Mob *mob, int64_t currTime) {
} }
} }
void MobAI::incNextMovement(Mob *mob, int64_t currTime) { void MobAI::incNextMovement(Mob *mob, time_t currTime) {
if (currTime == 0) if (currTime == 0)
currTime = getTime(); currTime = getTime();
@@ -648,7 +648,7 @@ void MobAI::incNextMovement(Mob *mob, int64_t currTime) {
mob->nextMovement = currTime + delay/2 + Rand::rand(delay/2); mob->nextMovement = currTime + delay/2 + Rand::rand(delay/2);
} }
static void roamingStep(Mob *mob, int64_t currTime) { static void roamingStep(Mob *mob, time_t currTime) {
/* /*
* We reuse nextAttack to avoid scanning for players all the time, but to still * We reuse nextAttack to avoid scanning for players all the time, but to still
* do so more often than if we waited for nextMovement (which is way too slow). * do so more often than if we waited for nextMovement (which is way too slow).
@@ -736,7 +736,7 @@ static void roamingStep(Mob *mob, int64_t currTime) {
} }
} }
static void retreatStep(Mob *mob, int64_t currTime) { static void retreatStep(Mob *mob, time_t currTime) {
if (mob->nextMovement != 0 && currTime < mob->nextMovement) if (mob->nextMovement != 0 && currTime < mob->nextMovement)
return; return;
@@ -781,7 +781,7 @@ static void retreatStep(Mob *mob, int64_t currTime) {
} }
} }
void MobAI::step(CombatNPC *npc, int64_t currTime) { void MobAI::step(CombatNPC *npc, time_t currTime) {
assert(npc->type == EntityType::MOB); assert(npc->type == EntityType::MOB);
auto mob = (Mob*)npc; auto mob = (Mob*)npc;

View File

@@ -13,32 +13,32 @@ enum class MobState {
namespace MobAI { namespace MobAI {
// needs to be declared before Mob's constructor // needs to be declared before Mob's constructor
void step(CombatNPC*, int64_t); void step(CombatNPC*, time_t);
}; };
struct Mob : public CombatNPC { struct Mob : public CombatNPC {
// general // general
MobState state = MobState::INACTIVE; MobState state = MobState::INACTIVE;
std::unordered_map<int32_t,int64_t> unbuffTimes = {}; std::unordered_map<int32_t,time_t> unbuffTimes = {};
// dead // dead
int64_t killedTime = 0; time_t killedTime = 0;
int64_t regenTime = 0; time_t regenTime = 0;
bool summoned = false; bool summoned = false;
bool despawned = false; // for the sake of death animations bool despawned = false; // for the sake of death animations
// roaming // roaming
int idleRange = 0; int idleRange = 0;
const int sightRange = 0; const int sightRange = 0;
int64_t nextMovement = 0; time_t nextMovement = 0;
bool staticPath = false; bool staticPath = false;
int roamX = 0, roamY = 0, roamZ = 0; int roamX = 0, roamY = 0, roamZ = 0;
// combat // combat
CNSocket *target = nullptr; CNSocket *target = nullptr;
int64_t nextAttack = 0; time_t nextAttack = 0;
int64_t lastDrainTime = 0; time_t lastDrainTime = 0;
int skillStyle = -1; // -1 for nothing, 0-2 for corruption, -2 for eruption int skillStyle = -1; // -1 for nothing, 0-2 for corruption, -2 for eruption
int hitX = 0, hitY = 0, hitZ = 0; // for use in ability targeting int hitX = 0, hitY = 0, hitZ = 0; // for use in ability targeting
@@ -98,8 +98,8 @@ namespace MobAI {
extern bool simulateMobs; extern bool simulateMobs;
// TODO: make this internal later // TODO: make this internal later
void incNextMovement(Mob *mob, int64_t currTime=0); void incNextMovement(Mob *mob, time_t currTime=0);
bool aggroCheck(Mob *mob, int64_t currTime); bool aggroCheck(Mob *mob, time_t currTime);
void clearDebuff(Mob *mob); void clearDebuff(Mob *mob);
void followToCombat(Mob *mob); void followToCombat(Mob *mob);
void groupRetreat(Mob *mob); void groupRetreat(Mob *mob);

View File

@@ -350,7 +350,7 @@ void NPCManager::queueNPCRemoval(int32_t id) {
RemovalQueue.push(id); RemovalQueue.push(id);
} }
static void step(CNServer *serv, int64_t currTime) { static void step(CNServer *serv, time_t currTime) {
for (auto& pair : NPCs) { for (auto& pair : NPCs) {
if (pair.second->type != EntityType::COMBAT_NPC && pair.second->type != EntityType::MOB) if (pair.second->type != EntityType::COMBAT_NPC && pair.second->type != EntityType::MOB)
continue; continue;

View File

@@ -79,10 +79,10 @@ struct Player : public Entity {
bool isBuddyBlocked[50] = {}; bool isBuddyBlocked[50] = {};
uint64_t iFirstUseFlag[2] = {}; uint64_t iFirstUseFlag[2] = {};
int64_t lastHeartbeat = 0; time_t lastHeartbeat = 0;
int suspicionRating = 0; int suspicionRating = 0;
int64_t lastShot = 0; time_t lastShot = 0;
std::vector<sItemBase> buyback = {}; std::vector<sItemBase> buyback = {};
Player() { type = EntityType::PLAYER; } Player() { type = EntityType::PLAYER; }

View File

@@ -11,7 +11,7 @@ struct EPInfo {
struct EPRace { struct EPRace {
std::set<int> collectedRings; std::set<int> collectedRings;
int mode, ticketSlot; int mode, ticketSlot;
int64_t startTime; time_t startTime;
}; };
namespace Racing { namespace Racing {

View File

@@ -319,7 +319,7 @@ static void stepNPCPathing() {
} }
} }
static void tickTransportationSystem(CNServer* serv, int64_t currTime) { static void tickTransportationSystem(CNServer* serv, time_t currTime) {
stepNPCPathing(); stepNPCPathing();
stepSkywaySystem(); stepSkywaySystem();
} }

View File

@@ -208,15 +208,15 @@ public:
}; };
class CNServer; class CNServer;
typedef void (*TimerHandler)(CNServer* serv, int64_t time); typedef void (*TimerHandler)(CNServer* serv, time_t time);
// timer struct // timer struct
struct TimerEvent { struct TimerEvent {
TimerHandler handlr; TimerHandler handlr;
int64_t delta; // time to be added to the current time on reset time_t delta; // time to be added to the current time on reset
int64_t scheduledEvent; // time to call handlr() time_t scheduledEvent; // time to call handlr()
TimerEvent(TimerHandler h, int64_t d): handlr(h), delta(d) { TimerEvent(TimerHandler h, time_t d): handlr(h), delta(d) {
scheduledEvent = 0; scheduledEvent = 0;
} }
}; };

View File

@@ -24,7 +24,7 @@ LoginMetadata* CNShared::getLoginMetadata(int64_t sk) {
return lm; return lm;
} }
void CNShared::pruneLoginMetadata(CNServer *serv, int64_t currTime) { void CNShared::pruneLoginMetadata(CNServer *serv, time_t currTime) {
std::lock_guard<std::mutex> lock(mtx); std::lock_guard<std::mutex> lock(mtx);
auto it = logins.begin(); auto it = logins.begin();

View File

@@ -19,11 +19,11 @@
struct LoginMetadata { struct LoginMetadata {
uint64_t FEKey; uint64_t FEKey;
int32_t playerId; int32_t playerId;
int64_t timestamp; time_t timestamp;
}; };
namespace CNShared { namespace CNShared {
void storeLoginMetadata(int64_t sk, LoginMetadata *lm); void storeLoginMetadata(int64_t sk, LoginMetadata *lm);
LoginMetadata* getLoginMetadata(int64_t sk); LoginMetadata* getLoginMetadata(int64_t sk);
void pruneLoginMetadata(CNServer *serv, int64_t currTime); void pruneLoginMetadata(CNServer *serv, time_t currTime);
} }

View File

@@ -45,8 +45,8 @@
std::string U16toU8(char16_t* src, size_t max); std::string U16toU8(char16_t* src, size_t max);
size_t U8toU16(std::string src, char16_t* des, size_t max); // returns number of char16_t that was written at des size_t U8toU16(std::string src, char16_t* des, size_t max); // returns number of char16_t that was written at des
int64_t getTime(); time_t getTime();
int64_t getTimestamp(); time_t getTimestamp();
void terminate(int); void terminate(int);
// The PROTOCOL_VERSION definition is defined by the build system. // The PROTOCOL_VERSION definition is defined by the build system.

View File

@@ -13,7 +13,7 @@ namespace Database {
int AccountID; int AccountID;
std::string Password; std::string Password;
int Selected; int Selected;
int64_t BannedUntil; time_t BannedUntil;
std::string BanReason; std::string BanReason;
}; };

View File

@@ -64,7 +64,7 @@ void terminate(int arg) {
} }
#ifdef _WIN32 #ifdef _WIN32
static BOOL WINAPI winTerminate(DWORD arg) { static BOOL winTerminate(DWORD arg) {
terminate(0); terminate(0);
return FALSE; return FALSE;
} }
@@ -201,21 +201,21 @@ size_t U8toU16(std::string src, char16_t* des, size_t max) {
return tmp.length(); return tmp.length();
} }
int64_t getTime() { time_t getTime() {
using namespace std::chrono; using namespace std::chrono;
milliseconds value = duration_cast<milliseconds>((time_point_cast<milliseconds>(steady_clock::now())).time_since_epoch()); milliseconds value = duration_cast<milliseconds>((time_point_cast<milliseconds>(steady_clock::now())).time_since_epoch());
return (int64_t)value.count(); return (time_t)value.count();
} }
// returns system time in seconds // returns system time in seconds
int64_t getTimestamp() { time_t getTimestamp() {
using namespace std::chrono; using namespace std::chrono;
seconds value = duration_cast<seconds>((time_point_cast<seconds>(system_clock::now())).time_since_epoch()); seconds value = duration_cast<seconds>((time_point_cast<seconds>(system_clock::now())).time_since_epoch());
return (int64_t)value.count(); return (time_t)value.count();
} }
// convert integer timestamp (in s) to FF systime struct // convert integer timestamp (in s) to FF systime struct

View File

@@ -574,8 +574,8 @@ void CNLoginServer::killConnection(CNSocket* cns) {
} }
void CNLoginServer::onStep() { void CNLoginServer::onStep() {
int64_t currTime = getTime(); time_t currTime = getTime();
static int64_t lastCheck = 0; static time_t lastCheck = 0;
if (currTime - lastCheck < 16000) if (currTime - lastCheck < 16000)
return; return;

View File

@@ -7,7 +7,7 @@
struct CNLoginData { struct CNLoginData {
int userID; int userID;
int64_t lastHeartbeat; time_t lastHeartbeat;
}; };
enum class LoginError { enum class LoginError {

View File

@@ -59,7 +59,7 @@ void CNShardServer::handlePacket(CNSocket* sock, CNPacketData* data) {
PlayerManager::players[sock]->lastHeartbeat = getTime(); PlayerManager::players[sock]->lastHeartbeat = getTime();
} }
void CNShardServer::keepAliveTimer(CNServer* serv, int64_t currTime) { void CNShardServer::keepAliveTimer(CNServer* serv, time_t currTime) {
for (auto& pair : PlayerManager::players) { for (auto& pair : PlayerManager::players) {
if (pair.second->lastHeartbeat != 0 && currTime - pair.second->lastHeartbeat > settings::TIMEOUT) { if (pair.second->lastHeartbeat != 0 && currTime - pair.second->lastHeartbeat > settings::TIMEOUT) {
// if the client hasn't responded in 60 seconds, its a dead connection so throw it out // if the client hasn't responded in 60 seconds, its a dead connection so throw it out
@@ -72,7 +72,7 @@ void CNShardServer::keepAliveTimer(CNServer* serv, int64_t currTime) {
} }
} }
void CNShardServer::periodicSaveTimer(CNServer* serv, int64_t currTime) { void CNShardServer::periodicSaveTimer(CNServer* serv, time_t currTime) {
if (PlayerManager::players.empty()) if (PlayerManager::players.empty())
return; return;
@@ -114,7 +114,7 @@ void CNShardServer::kill() {
} }
void CNShardServer::onStep() { void CNShardServer::onStep() {
int64_t currTime = getTime(); time_t currTime = getTime();
// do not evaluate timers if the server is shutting down // do not evaluate timers if the server is shutting down
if (!active) if (!active)

View File

@@ -11,8 +11,8 @@ class CNShardServer : public CNServer {
private: private:
static void handlePacket(CNSocket* sock, CNPacketData* data); static void handlePacket(CNSocket* sock, CNPacketData* data);
static void keepAliveTimer(CNServer*, int64_t); static void keepAliveTimer(CNServer*, time_t);
static void periodicSaveTimer(CNServer* serv, int64_t currTime); static void periodicSaveTimer(CNServer* serv, time_t currTime);
public: public:
static std::map<uint32_t, PacketHandler> ShardPackets; static std::map<uint32_t, PacketHandler> ShardPackets;

View File

@@ -72,7 +72,7 @@ static int process_email(char *buff, std::string email) {
return i; return i;
} }
static void tick(CNServer *serv, int64_t delta) { static void tick(CNServer *serv, time_t delta) {
std::lock_guard<std::mutex> lock(sockLock); std::lock_guard<std::mutex> lock(sockLock);
char buff[BUFSIZE]; char buff[BUFSIZE];
int n; int n;

View File

@@ -17,7 +17,7 @@ int settings::DBSAVEINTERVAL = 240;
int settings::SHARDPORT = 23001; int settings::SHARDPORT = 23001;
std::string settings::SHARDSERVERIP = "127.0.0.1"; std::string settings::SHARDSERVERIP = "127.0.0.1";
bool settings::LOCALHOSTWORKAROUND = true; bool settings::LOCALHOSTWORKAROUND = true;
int64_t settings::TIMEOUT = 60000; time_t settings::TIMEOUT = 60000;
int settings::VIEWDISTANCE = 25600; int settings::VIEWDISTANCE = 25600;
bool settings::SIMULATEMOBS = true; bool settings::SIMULATEMOBS = true;
bool settings::ANTICHEAT = true; bool settings::ANTICHEAT = true;

View File

@@ -11,7 +11,7 @@ namespace settings {
extern std::string SHARDSERVERIP; extern std::string SHARDSERVERIP;
extern bool LOCALHOSTWORKAROUND; extern bool LOCALHOSTWORKAROUND;
extern bool ANTICHEAT; extern bool ANTICHEAT;
extern int64_t TIMEOUT; extern time_t TIMEOUT;
extern int VIEWDISTANCE; extern int VIEWDISTANCE;
extern bool SIMULATEMOBS; extern bool SIMULATEMOBS;
extern int SPAWN_X; extern int SPAWN_X;

View File

@@ -24,6 +24,7 @@
#ifdef _WIN32 || _WIN64 #ifdef _WIN32 || _WIN64
// On windows we need to generate random bytes differently. // On windows we need to generate random bytes differently.
typedef __int64 ssize_t;
#define BCRYPT_HASHSIZE 60 #define BCRYPT_HASHSIZE 60
#include "bcrypt.h" #include "bcrypt.h"
@@ -50,7 +51,6 @@ static int try_close(int fd)
return ret; return ret;
} }
#ifndef _WIN32
static int try_read(int fd, char *out, size_t count) static int try_read(int fd, char *out, size_t count)
{ {
size_t total; size_t total;
@@ -75,7 +75,6 @@ static int try_read(int fd, char *out, size_t count)
return 0; return 0;
} }
#endif
/* /*
* This is a best effort implementation. Nothing prevents a compiler from * This is a best effort implementation. Nothing prevents a compiler from