Skip to content

Commit 74aabfd

Browse files
committed
fix: sync bugs
1 parent 008eece commit 74aabfd

File tree

3 files changed

+34
-13
lines changed

3 files changed

+34
-13
lines changed

src/OTAPI.UnifiedServerProcess.GlobalNetwork/Network/Router.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ public class Router
1313
public int ListenPort { get; private set; }
1414
public static readonly RemoteClient[] globalClients = new RemoteClient[256];
1515
public static readonly MessageBuffer[] globalMsgBuffers = new MessageBuffer[257];
16-
public readonly ServerContext[] clientCurrentlyServers = new ServerContext[256];
16+
readonly ServerContext[] clientCurrentlyServers = new ServerContext[256];
17+
public ServerContext GetClientCurrentlyServer(int clientIndex) => Volatile.Read(ref clientCurrentlyServers[clientIndex]);
18+
public void SetClientCurrentlyServer(int clientIndex, ServerContext server) => Volatile.Write(ref clientCurrentlyServers[clientIndex], server);
19+
1720
static Router() {
1821
for (int i = 0; i < 256; i++) {
1922
globalClients[i] = new RemoteClient() {
@@ -50,13 +53,13 @@ public Router(int listenPort, ServerContext main, params ServerContext[] allServ
5053
}
5154

5255
private bool NetMessageSystemContext_CheckCanSend(On.Terraria.NetMessageSystemContext.orig_CheckCanSend orig, NetMessageSystemContext self, int clientIndex) {
53-
return clientCurrentlyServers[clientIndex] == self.root && globalClients[clientIndex].IsConnected();
56+
return GetClientCurrentlyServer(clientIndex) == self.root && globalClients[clientIndex].IsConnected();
5457
}
5558

5659
private void UpdateServerInMainThread(On.Terraria.NetplaySystemContext.orig_mfwh_UpdateServerInMainThread orig, NetplaySystemContext self) {
5760
var server = self.root;
5861
for (int i = 0; i < 256; i++) {
59-
if (server != clientCurrentlyServers[i]) {
62+
if (server != GetClientCurrentlyServer(i)) {
6063
continue;
6164
}
6265
if (server.NetMessage.buffer[i].checkBytes) {
@@ -93,7 +96,7 @@ private void ProcessBytes(On.Terraria.NetMessageSystemContext.orig_mfwh_CheckByt
9396
unreadLength -= packetLength;
9497
readPosition += packetLength;
9598

96-
if (clientCurrentlyServers[clientIndex] != server) {
99+
if (GetClientCurrentlyServer(clientIndex) != server) {
97100
// If there is unprocessed data remaining, copy it to the beginning of the buffer for the next processing round.
98101
// Update buffer.totalData with the remaining byte count to prevent reprocessing of this data.
99102
for (int i = 0; i < unreadLength; i++) {
@@ -158,7 +161,7 @@ private void UpdateConnectedClients() {
158161
try {
159162
for (int i = 0; i < 256; i++) {
160163
var client = globalClients[i];
161-
var server = clientCurrentlyServers[i];
164+
var server = GetClientCurrentlyServer(i);
162165

163166
if (client.PendingTermination) {
164167
if (client.PendingTerminationApproved) {
@@ -171,7 +174,7 @@ private void UpdateConnectedClients() {
171174
server.Player.Hooks.PlayerDisconnect(i);
172175
}
173176

174-
clientCurrentlyServers[i] = main;
177+
SetClientCurrentlyServer(i, main);
175178
}
176179
continue;
177180
}
@@ -283,7 +286,7 @@ void LaunchBroadcast() {
283286
void OnConnectionAccepted(ISocket client) {
284287
int id = FindNextEmptyClientSlot();
285288
if (id != -1) {
286-
clientCurrentlyServers[id] = main;
289+
SetClientCurrentlyServer(id, main);
287290
globalClients[id].Reset(main);
288291
globalClients[id].Socket = client;
289292
}
@@ -307,7 +310,7 @@ int FindNextEmptyClientSlot() {
307310
}
308311

309312
public void ServerWarp(byte plr, ServerContext to) {
310-
var from = clientCurrentlyServers[plr];
313+
var from = GetClientCurrentlyServer(plr);
311314

312315
if (from == to) {
313316
return;
@@ -331,7 +334,7 @@ public void ServerWarp(byte plr, ServerContext to) {
331334
inactivePlayer.active = false;
332335
activePlayer.active = true;
333336

334-
clientCurrentlyServers[plr] = to;
337+
SetClientCurrentlyServer(plr, to);
335338
client.ResetSections(to);
336339

337340
SyncHelper.SyncServerOnlineToPlayer(to, plr);

src/OTAPI.UnifiedServerProcess.GlobalNetwork/Network/SyncHelper.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ static void SendSectionsWhenJoin(this ServerContext server, int whoAmI) {
3737
List<Point> existingPos = new((spawnSectionXEnd - spawnSectionXBegin) * (spawnSectionYEnd - spawnSectionYBegin));
3838
for (int x = spawnSectionXBegin; x < spawnSectionXEnd; x++) {
3939
for (int y = spawnSectionYBegin; y < spawnSectionYEnd; y++) {
40-
server.NetMessage.SendSection(x, y, whoAmI);
40+
server.NetMessage.SendSection(whoAmI, x, y);
4141
existingPos.Add(new Point(x, y));
4242
}
4343
}
4444
server.PortalHelper.SyncPortalsOnPlayerJoin(whoAmI, 1, existingPos, out var portalSections);
4545
foreach (var section in portalSections) {
46-
server.NetMessage.SendSection(section.X, section.Y, whoAmI);
46+
server.NetMessage.SendSection(whoAmI, section.X, section.Y);
4747
}
4848
}
4949
static void SendWorldEntities(this ServerContext server, int whoAmI) {
@@ -79,7 +79,25 @@ static void SendWorldInfo(this ServerContext server, int whoAmI) {
7979
#endregion
8080

8181
#region Sync Server Offline To Player
82+
static void SendRawData(ServerContext offlineServer, int plr, byte[] data, int offset, int count) {
83+
var client = offlineServer.Netplay.Clients[plr];
84+
offlineServer.Hooks.NetMessage.InvokeSendBytes(client.Socket, data, offset, count, delegate (object state) {
85+
client.ServerWriteCallBack(offlineServer, state);
86+
},
87+
null, plr);
88+
}
8289
public static void SyncServerOfflineToPlayer(ServerContext offlineServer, int plr) {
90+
byte[] data = [6, 0, MessageID.ItemOwner, default, default, 255];
91+
for (int i = 0; i < Terraria.Main.maxItems; i++) {
92+
var item = offlineServer.Main.item[i];
93+
if (!item.active || item.playerIndexTheItemIsReservedFor != plr) {
94+
continue;
95+
}
96+
short itemSlot = (short)i;
97+
data[3] = (byte)(itemSlot & 0xFF);
98+
data[4] = (byte)(itemSlot >> 8);
99+
SendRawData(offlineServer, plr, data, 0, 6);
100+
}
83101
for (int i = 0; i < Terraria.Main.maxProjectiles; i++) {
84102
var proj = offlineServer.Main.projectile[i];
85103
if (!proj.active) {
@@ -89,7 +107,7 @@ public static void SyncServerOfflineToPlayer(ServerContext offlineServer, int pl
89107
}
90108
for (int i = 0; i < Terraria.Main.maxPlayers; i++) {
91109
var player = offlineServer.Main.player[i];
92-
if (!player.active) {
110+
if (!player.active) {
93111
continue;
94112
}
95113
offlineServer.NetMessage.TrySendData(MessageID.PlayerActive, plr, i, null, i, 0);
@@ -102,7 +120,6 @@ public static void SyncPlayerJoinToOthers(ServerContext onlineServer, int whoAmI
102120
var player = onlineServer.Main.player[whoAmI];
103121
onlineServer.NetMessage.TrySendData(MessageID.PlayerActive, -1, whoAmI, null, whoAmI);
104122
onlineServer.NetMessage.TrySendData(MessageID.SyncPlayer, -1, whoAmI, null, whoAmI);
105-
onlineServer.NetMessage.TrySendData(68, -1, whoAmI, null, whoAmI);
106123
onlineServer.NetMessage.TrySendData(MessageID.PlayerLifeMana, -1, whoAmI, null, whoAmI);
107124
onlineServer.NetMessage.TrySendData(42, -1, whoAmI, null, whoAmI);
108125
onlineServer.NetMessage.TrySendData(MessageID.PlayerBuffs, -1, whoAmI, null, whoAmI);

src/OTAPI.UnifiedServerProcess.GlobalNetwork/Servers/ServerContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ public ServerContext(string worldName, byte[] worldFileData) : base(worldName) {
1919
Netplay.ListenPort = -1;
2020
Netplay.UseUPNP = true;
2121
}
22+
public override string ToString() => $"{{ Type:ServerContext, Name:\"{Name}\", Players:{Main.player.Count(p => p.active)} }}";
2223
}
2324
}

0 commit comments

Comments
 (0)