mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
Every MASTER service packet is now an LUBitStream struct (docs/PacketArchitecture.md, PR 14) and the master server's switch is a dispatch map (PacketDispatcher), as are the master handlers of the world, chat and dashboard servers. - dNet/MasterPackets.h: RequestZoneTransfer, RequestZoneTransferResponse, ServerInfo, RequestSessionKey, SetSessionKey, SessionKeyResponse, NewSessionAlert, PlayerAdded / PlayerRemoved, CreatePrivateZone, RequestPrivateZone (passwords still cut to 50 characters when read), WorldReady, WorldReadyInfo (WORLD_READY to the dashboard), PrepZone, Shutdown, ShutdownResponse, WorldShutDown (SHUTDOWN_RESPONSE to the dashboard), ShutdownUniverse, AffirmTransferRequest/Response, RequestServerList, ServerListResponse, DashboardShutdown, ConfigReload, InstanceShutdown. The Send* functions are gone; MasterPackets::SendToMaster(msg) and SendTo(sysAddr, msg) send a struct. - The dashboard and instance migration structs (PlayerAction, DataChanged, Dashboard messages, MessageCapture, InstanceMigration) are LUBitStreams of the MASTER service now and moved to dNet/master/, included by MasterPackets.h. Their payloads are unchanged; master forwards them by re-serializing the struct instead of copying raw bytes. - InstanceManager, ZoneInstanceManager, MigrationCoordinator, dServer (server info, zone transfer response), auth (SET_SESSION_KEY), the world (session keys, player added and removed, world ready, shutdown response, affirmations, prep zone, shutdown universe) and the dashboard (server list, instance shutdown, config reload, announcements, player actions, message capture) send and read structs. - The login stamps are a `stamps` field of RequestZoneTransfer and RequestZoneTransferResponse (read leniently as before: a message without them reads as empty); master adds its stamps in the REQUEST_ZONE_TRANSFER handler and when it answers, as it did. - InstanceManager::GetInstanceBySysAddr takes a const address. Verified: tests/dGameTests/dNetTests/Legacy/MasterPacketsLegacy.h is a verbatim copy of the old writers and readers; MasterPacketsTests requires identical bytes for a grid of inputs, checks the old readers read what the structs write, round trips and truncation, hand written golden packets, that zone transfers without stamps still read, that the dashboard/migration structs write what "header + Serialize" wrote, and that the dispatcher drops truncated packets. No wire bytes changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
2.8 KiB
C++
65 lines
2.8 KiB
C++
#ifndef __WORLDMIGRATION__H__
|
|
#define __WORLDMIGRATION__H__
|
|
|
|
#include <functional>
|
|
|
|
#include "master/InstanceMigration.h"
|
|
#include "RakNetTypes.h"
|
|
#include "dCommonVars.h"
|
|
|
|
class Entity;
|
|
|
|
/**
|
|
* A world server's side of instance migrations (InstanceMigration.h, docs/SeamlessTransfer.md).
|
|
*
|
|
* As the source: warns everyone with the client's own "Mythran Maintenance Alert", then moves players a few at a
|
|
* time. Each is saved (position included), locked (their packets are ignored and they aren't saved again when they
|
|
* disconnect, so nothing they do after the save can be lost or duplicated), and sent TRANSFER_TO_WORLD with the
|
|
* Mythran shift flag. As the target: puts back what was carried over (the pet that was out) once they have loaded.
|
|
* GMs start migrations with /replaceinstance and /mergeinstance.
|
|
*/
|
|
namespace WorldMigration {
|
|
// What a disconnect runs (save and remove the user); used to drop players whose client never left
|
|
void SetCleanupHandler(std::function<void(const SystemAddress&)> handler);
|
|
|
|
// MIGRATE_PLAYERS from master (a target port of 0 cancels the running migration)
|
|
void HandleOrder(const MigratePlayersOrder& order);
|
|
|
|
// MIGRATE_PLAYER_STATE from master: a player on their way here
|
|
void StoreCarriedState(const CarriedPlayerState& state);
|
|
|
|
// Every world frame
|
|
void Update(float deltaTime);
|
|
|
|
// The player was sent away: ignore their packets, and don't save them again when they disconnect
|
|
bool IsLeaving(const SystemAddress& sysAddr);
|
|
|
|
// Their connection closed; forget them
|
|
void OnDisconnected(const SystemAddress& sysAddr);
|
|
|
|
// A player finished loading here (PLAYER_LOADED)
|
|
void OnPlayerLoaded(Entity* player);
|
|
|
|
// Experimental seamless migration: this character is on its way and its client kept the zone loaded, so it must
|
|
// not be sent LOAD_STATIC_ZONE (that tears the scene down); load it at once instead
|
|
bool ArrivesSeamlessly(LWOOBJID characterId);
|
|
|
|
// Its player entity was created and constructed: run what the client's PlayerLoaded would have
|
|
void OnSeamlessArrival(Entity* player);
|
|
|
|
// MIGRATE_STATUS from master: tell the GM who asked, if they are here
|
|
void HandleStatus(const MigrationStatus& status);
|
|
|
|
// Ask master to move everyone in this instance; the seam a dashboard or other tool can use too, by sending
|
|
// INSTANCE_MIGRATE to master
|
|
void RequestMigration(Entity* requester, InstanceMigration::eKind kind, uint32_t targetInstance, uint16_t warnSeconds, bool seamless);
|
|
|
|
// /replaceinstance [warn seconds] [seamless]
|
|
void ReplaceInstanceCommand(Entity* entity, const SystemAddress& sysAddr, const std::string args);
|
|
|
|
// /mergeinstance [target instance, 0 for the best fit] [warn seconds] [seamless]
|
|
void MergeInstanceCommand(Entity* entity, const SystemAddress& sysAddr, const std::string args);
|
|
}
|
|
|
|
#endif //!__WORLDMIGRATION__H__
|