Compare commits

...

3 Commits

Author SHA1 Message Date
eb8e54c1f0 Do not evaluate timers if the server is shutting down
This should fix issues with segfaults when the server is being
terminated that sometimes occur because things like NPC path traversal
keep running while the process is executing the signal handler.
2022-11-27 22:33:55 +01:00
1ba0f5e14a Mention Linux instructions in README.md
Also clarify the line about CI binaries.
2022-11-26 20:30:07 +01:00
12dde394c0 Add undocumented config option to disable rapid fire anticheat
This quick hack has been around for a while, so we might as well make it
configurable.

Also updated tdata reference.
2022-11-26 19:36:10 +01:00
6 changed files with 30 additions and 12 deletions

View File

@ -25,6 +25,8 @@ OpenFusion is a reverse-engineered server for FusionFall. It primarily targets v
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.
5. 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 4. 5. 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 4.
Instructions for getting the client to run on Linux through Wine can be found [here](https://github.com/OpenFusionProject/OpenFusion/wiki/Running-the-game-client-on-Linux).
### 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.4-original.zip` or `OpenFusionServer-1.4-academy.zip` from [here](https://github.com/OpenFusionProject/OpenFusion/releases/tag/1.4).
@ -35,7 +37,7 @@ OpenFusion is a reverse-engineered server for FusionFall. It primarily targets v
3. Lastly Game Version - select `beta-20100104` if you downloaded the original zip, or `beta-20111013` if you downloaded the academy zip. 3. Lastly Game Version - select `beta-20100104` if you downloaded the original zip, or `beta-20111013` if you downloaded the academy zip.
5. Once you've added the server to the list, connect to it and log in. If you're having trouble with this, refer to steps 4 and 5 from the previous section. 5. Once you've added the server to the list, connect to it and log in. If you're having trouble with this, refer to steps 4 and 5 from the previous section.
If you want, [compiled binaries (artifacts) for each functional commit can be found here.](http://cdn.dexlabs.systems/of-builds/) If you want to run the latest development builds of the server, [compiled binaries (artifacts) for each functional commit can be found here.](http://cdn.dexlabs.systems/of-builds/)
For a more detailed overview of the game's architecture and how to configure it, read the following sections. For a more detailed overview of the game's architecture and how to configure it, read the following sections.

View File

@ -56,14 +56,10 @@ static std::pair<int,int> getDamage(int attackPower, int defensePower, bool shou
return ret; return ret;
} }
static void pcAttackNpcs(CNSocket *sock, CNPacketData *data) { static bool checkRapidFire(CNSocket *sock, int targetCount) {
auto pkt = (sP_CL2FE_REQ_PC_ATTACK_NPCs*)data->buf;
Player *plr = PlayerManager::getPlayer(sock); Player *plr = PlayerManager::getPlayer(sock);
auto targets = (int32_t*)data->trailers;
// rapid fire anti-cheat
// TODO: move this out of here, when generalizing packet frequency validation
time_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)
@ -71,15 +67,28 @@ static void pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
plr->lastShot = currTime; plr->lastShot = currTime;
if (pkt->iNPCCnt > 3) // 3+ targets should never be possible // 3+ targets should never be possible
if (targetCount > 3)
plr->suspicionRating += 10000; plr->suspicionRating += 10000;
if (plr->suspicionRating > 10000) { // kill the socket when the player is too suspicious // kill the socket when the player is too suspicious
if (plr->suspicionRating > 10000) {
sock->kill(); sock->kill();
CNShardServer::_killConnection(sock); CNShardServer::_killConnection(sock);
return; return true;
} }
return false;
}
static void pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
auto pkt = (sP_CL2FE_REQ_PC_ATTACK_NPCs*)data->buf;
Player *plr = PlayerManager::getPlayer(sock);
auto targets = (int32_t*)data->trailers;
// kick the player if firing too rapidly
if (settings::ANTICHEAT && checkRapidFire(sock, pkt->iNPCCnt))
return;
/* /*
* IMPORTANT: This validates memory safety in addition to preventing * IMPORTANT: This validates memory safety in addition to preventing

View File

@ -115,6 +115,10 @@ void CNShardServer::kill() {
void CNShardServer::onStep() { void CNShardServer::onStep() {
time_t currTime = getTime(); time_t currTime = getTime();
// do not evaluate timers if the server is shutting down
if (!active)
return;
for (TimerEvent& event : Timers) { for (TimerEvent& event : Timers) {
if (event.scheduledEvent == 0) { if (event.scheduledEvent == 0) {
// event hasn't been queued yet, go ahead and do that // event hasn't been queued yet, go ahead and do that

View File

@ -20,6 +20,7 @@ bool settings::LOCALHOSTWORKAROUND = true;
time_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;
// default spawn point // default spawn point
#ifndef ACADEMY #ifndef ACADEMY
@ -108,6 +109,7 @@ void settings::init() {
ACCLEVEL = reader.GetInteger("shard", "accountlevel", ACCLEVEL); ACCLEVEL = reader.GetInteger("shard", "accountlevel", ACCLEVEL);
EVENTMODE = reader.GetInteger("shard", "eventmode", EVENTMODE); EVENTMODE = reader.GetInteger("shard", "eventmode", EVENTMODE);
DISABLEFIRSTUSEFLAG = reader.GetBoolean("shard", "disablefirstuseflag", DISABLEFIRSTUSEFLAG); DISABLEFIRSTUSEFLAG = reader.GetBoolean("shard", "disablefirstuseflag", DISABLEFIRSTUSEFLAG);
ANTICHEAT = reader.GetBoolean("shard", "anticheat", ANTICHEAT);
MONITORENABLED = reader.GetBoolean("monitor", "enabled", MONITORENABLED); MONITORENABLED = reader.GetBoolean("monitor", "enabled", MONITORENABLED);
MONITORPORT = reader.GetInteger("monitor", "port", MONITORPORT); MONITORPORT = reader.GetInteger("monitor", "port", MONITORPORT);
MONITORINTERVAL = reader.GetInteger("monitor", "interval", MONITORINTERVAL); MONITORINTERVAL = reader.GetInteger("monitor", "interval", MONITORINTERVAL);

View File

@ -10,6 +10,7 @@ namespace settings {
extern int SHARDPORT; extern int SHARDPORT;
extern std::string SHARDSERVERIP; extern std::string SHARDSERVERIP;
extern bool LOCALHOSTWORKAROUND; extern bool LOCALHOSTWORKAROUND;
extern bool ANTICHEAT;
extern time_t TIMEOUT; extern time_t TIMEOUT;
extern int VIEWDISTANCE; extern int VIEWDISTANCE;
extern bool SIMULATEMOBS; extern bool SIMULATEMOBS;

2
tdata

@ -1 +1 @@
Subproject commit 8230fb8649d6da8de71e918c24efbb55d1c08a88 Subproject commit cc65dbb402b5baa2b604ed66132edd88cc82a52a