Compare commits

...

3 Commits

Author SHA1 Message Date
Juansecu
12fa21f87e
Merge 2096c3c3cc into 17362b2ea6 2024-06-29 20:12:12 +10:00
Gent Semaj
17362b2ea6
Client synchronization improvements (#283)
* Client synchronization improvements

* Remove bad comment

* Remove guard on PC_TICK

* Fix delayed loading of nano skill icons

We actually don't need to wait for post-load to do the second nano book send.
That adds unnecessary delay. Moving it to right after `P_FE2CL_REP_PC_ENTER_SUCC`
does the trick and gives the client plenty of time to fetch the icons before
loading in-game.

* Don't send unnecessary nano book subsets pre-enter

* Fix comment
2024-06-27 08:19:54 -05:00
Juansecu
2096c3c3cc BUILD - Optimize Dockerfile by using alpine as base image 2024-06-08 21:55:03 -05:00
6 changed files with 42 additions and 35 deletions

View File

@ -1,28 +1,33 @@
# build
FROM debian:stable-slim as build
FROM alpine:3 as build
WORKDIR /usr/src/app
RUN apt-get -y update && apt-get install -y \
RUN apk update && apk upgrade && apk add \
linux-headers \
git \
clang \
clang18 \
make \
libsqlite3-dev
sqlite-dev
COPY src ./src
COPY vendor ./vendor
COPY .git ./.git
COPY Makefile CMakeLists.txt version.h.in ./
RUN sed -i 's/^CC=clang$/&-18/' Makefile
RUN sed -i 's/^CXX=clang++$/&-18/' Makefile
RUN make -j8
# prod
FROM debian:stable-slim
FROM alpine:3
WORKDIR /usr/src/app
RUN apt-get -y update && apt-get install -y \
libsqlite3-dev
RUN apk update && apk upgrade && apk add \
libstdc++ \
sqlite-dev
COPY --from=build /usr/src/app/bin/fusion /bin/fusion
COPY sql ./sql

View File

@ -30,7 +30,7 @@ static bool playerHasBuddyWithID(Player* plr, int buddyID) {
#pragma endregion
// Refresh buddy list
void Buddies::refreshBuddyList(CNSocket* sock) {
void Buddies::sendBuddyList(CNSocket* sock) {
Player* plr = PlayerManager::getPlayer(sock);
int buddyCnt = Database::getNumBuddies(plr);
@ -278,15 +278,6 @@ static void reqFindNameBuddyAccept(CNSocket* sock, CNPacketData* data) {
static void reqPktGetBuddyState(CNSocket* sock, CNPacketData* data) {
Player* plr = PlayerManager::getPlayer(sock);
/*
* If the buddy list wasn't synced a second time yet, sync it.
* Not sure why we have to do it again for the client not to trip up.
*/
if (!plr->buddiesSynced) {
refreshBuddyList(sock);
plr->buddiesSynced = true;
}
INITSTRUCT(sP_FE2CL_REP_GET_BUDDY_STATE_SUCC, resp);
for (int slot = 0; slot < 50; slot++) {

View File

@ -6,5 +6,5 @@ namespace Buddies {
void init();
// Buddy list
void refreshBuddyList(CNSocket* sock);
void sendBuddyList(CNSocket* sock);
}

View File

@ -72,8 +72,8 @@ struct Player : public Entity, public ICombatant {
bool notify = false;
bool hidden = false;
bool unwarpable = false;
bool initialLoadDone = false;
bool buddiesSynced = false;
int64_t buddyIDs[50] = {};
bool isBuddyBlocked[50] = {};

View File

@ -155,16 +155,21 @@ void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) {
* Nanos the player hasn't unlocked will (and should) be greyed out. Thus, all nanos should be accounted
* for in these packets, even if the player hasn't unlocked them.
*/
static void sendNanoBookSubset(CNSocket *sock) {
static void sendNanoBook(CNSocket *sock, Player *plr, bool resizeOnly) {
#ifdef ACADEMY
Player *plr = getPlayer(sock);
int16_t id = 0;
INITSTRUCT(sP_FE2CL_REP_NANO_BOOK_SUBSET, pkt);
pkt.PCUID = plr->iID;
pkt.bookSize = NANO_COUNT;
if (resizeOnly) {
// triggers nano array resizing without
// actually sending nanos
sock->sendPacket(pkt, P_FE2CL_REP_NANO_BOOK_SUBSET);
return;
}
while (id < NANO_COUNT) {
pkt.elementOffset = id;
@ -295,27 +300,21 @@ static void enterPlayer(CNSocket* sock, CNPacketData* data) {
sock->setFEKey(lm->FEKey);
sock->setActiveKey(SOCKETKEY_FE); // send all packets using the FE key from now on
// Academy builds receive nanos in a separate packet. An initial one with the size of the
// nano book needs to be sent before PC_ENTER_SUCC so the client can resize its nano arrays,
// and then proper packets with the nanos included must be sent after, while the game is loading.
sendNanoBook(sock, plr, true);
sock->sendPacket(response, P_FE2CL_REP_PC_ENTER_SUCC);
// transmit MOTD after entering the game, so the client hopefully changes modes on time
Chat::sendServerMessage(sock, settings::MOTDSTRING);
sendNanoBook(sock, plr, false);
// transfer ownership of Player object into the shard (still valid in this function though)
addPlayer(sock, plr);
// check if there is an expiring vehicle
Items::checkItemExpire(sock, plr);
// set player equip stats
Items::setItemStats(plr);
Missions::failInstancedMissions(sock);
sendNanoBookSubset(sock);
// initial buddy sync
Buddies::refreshBuddyList(sock);
for (auto& pair : players)
if (pair.second->notify)
Chat::sendServerMessage(pair.first, "[ADMIN]" + getPlayerName(plr) + " has joined.");
@ -378,6 +377,17 @@ static void loadPlayer(CNSocket* sock, CNPacketData* data) {
sock->sendPacket(pkt, P_FE2CL_INSTANCE_MAP_INFO);
}
if (!plr->initialLoadDone) {
// these should be called only once, but not until after
// first load-in or else the client may ignore the packets
Chat::sendServerMessage(sock, settings::MOTDSTRING); // MOTD
Missions::failInstancedMissions(sock); // auto-fail missions
Buddies::sendBuddyList(sock); // buddy list
Items::checkItemExpire(sock, plr); // vehicle expiration
plr->initialLoadDone = true;
}
}
static void heartbeatPlayer(CNSocket* sock, CNPacketData* data) {

View File

@ -1,5 +1,6 @@
#pragma once
#include <stdint.h>
#include <string>
namespace settings {
@ -13,7 +14,7 @@ namespace settings {
extern std::string SHARDSERVERIP;
extern bool LOCALHOSTWORKAROUND;
extern bool ANTICHEAT;
extern time_t TIMEOUT;
extern int64_t TIMEOUT;
extern int VIEWDISTANCE;
extern bool SIMULATEMOBS;
extern int SPAWN_X;