mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-23 01:21:57 -05:00
Workaround for server software that sends AddEntity then AddExtPlayerName with different player ids.
This caused duplicate tab list entry ids. Only seems to be an issue with MCForge-Redux
This commit is contained in:
parent
32a00ecd88
commit
674609f5ee
5 changed files with 46 additions and 21 deletions
|
@ -23,7 +23,7 @@ namespace ClassicalSharp.Network {
|
|||
needD3Fix = false; game.UseCPEBlocks = false;
|
||||
|
||||
NetworkProcessor net = (NetworkProcessor)game.Server;
|
||||
net.ResetProtocols();
|
||||
net.Reset();
|
||||
}
|
||||
|
||||
/// <summary> Sets fields / updates network handles based on the server
|
||||
|
|
|
@ -8,6 +8,8 @@ namespace ClassicalSharp.Network {
|
|||
|
||||
public partial class NetworkProcessor : IServerConnection {
|
||||
|
||||
internal bool addEntityHack = true;
|
||||
|
||||
public override void SendChat(string text, bool partial) {
|
||||
if (String.IsNullOrEmpty(text)) return;
|
||||
classic.SendChat(text, partial);
|
||||
|
@ -70,14 +72,22 @@ namespace ClassicalSharp.Network {
|
|||
game.Entities[id] = null;
|
||||
}
|
||||
|
||||
// See comment about LegendCraft in HandleAddEntity
|
||||
// See comment about some servers in HandleAddEntity
|
||||
int mask = id >> 3, bit = 1 << (id & 0x7);
|
||||
if ((needRemoveNames[mask] & bit) == 0) return;
|
||||
game.EntityEvents.RaiseTabEntryRemoved(id);
|
||||
game.TabList.Entries[id] = null;
|
||||
if (!addEntityHack || (needRemoveNames[mask] & bit) == 0) return;
|
||||
|
||||
RemoveTablistEntry(id);
|
||||
needRemoveNames[mask] &= (byte)~bit;
|
||||
}
|
||||
|
||||
internal void UpdateLocation(byte playerId, LocationUpdate update, bool interpolate) {
|
||||
Entity entity = game.Entities[playerId];
|
||||
if (entity != null) {
|
||||
entity.SetLocation(update, interpolate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal void AddTablistEntry(byte id, string playerName, string listName,
|
||||
string groupName, byte groupRank) {
|
||||
TabListEntry oldInfo = game.TabList.Entries[id];
|
||||
|
@ -87,7 +97,7 @@ namespace ClassicalSharp.Network {
|
|||
if (oldInfo != null) {
|
||||
// Only redraw the tab list if something changed.
|
||||
if (info.PlayerName != oldInfo.PlayerName || info.ListName != oldInfo.ListName ||
|
||||
info.GroupName != oldInfo.GroupName || info.GroupRank != oldInfo.GroupRank) {
|
||||
info.GroupName != oldInfo.GroupName || info.GroupRank != oldInfo.GroupRank) {
|
||||
game.EntityEvents.RaiseTabListEntryChanged(id);
|
||||
}
|
||||
} else {
|
||||
|
@ -95,10 +105,21 @@ namespace ClassicalSharp.Network {
|
|||
}
|
||||
}
|
||||
|
||||
internal void UpdateLocation(byte playerId, LocationUpdate update, bool interpolate) {
|
||||
Entity entity = game.Entities[playerId];
|
||||
if (entity != null) {
|
||||
entity.SetLocation(update, interpolate);
|
||||
internal void RemoveTablistEntry(byte id) {
|
||||
game.EntityEvents.RaiseTabEntryRemoved(id);
|
||||
game.TabList.Entries[id] = null;
|
||||
}
|
||||
|
||||
internal void DisableAddEntityHack() {
|
||||
if (!addEntityHack) return;
|
||||
addEntityHack = false;
|
||||
|
||||
for (int id = 0; id < EntityList.MaxCount; id++) {
|
||||
int mask = id >> 3, bit = 1 << (id & 0x7);
|
||||
if ((needRemoveNames[mask] & bit) == 0) continue;
|
||||
|
||||
RemoveTablistEntry((byte)id);
|
||||
needRemoveNames[mask] &= (byte)~bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,11 +164,12 @@ namespace ClassicalSharp.Network {
|
|||
reader.Skip(packetSizes[(byte)opcode] - 1);
|
||||
}
|
||||
|
||||
internal void ResetProtocols() {
|
||||
internal void Reset() {
|
||||
UsingExtPlayerList = false;
|
||||
UsingPlayerClick = false;
|
||||
SupportsPartialMessages = false;
|
||||
SupportsFullCP437 = false;
|
||||
addEntityHack = true;
|
||||
|
||||
for (int i = 0; i < handlers.Length; i++)
|
||||
handlers[i] = null;
|
||||
|
|
|
@ -125,6 +125,10 @@ namespace ClassicalSharp.Network.Protocols {
|
|||
string groupName = reader.ReadAsciiString();
|
||||
byte groupRank = reader.ReadUInt8();
|
||||
|
||||
// Some server software will declare they support ExtPlayerList, but send AddEntity then AddPlayerName
|
||||
// we need to workaround this case by removing all the tab names we added for the AddEntity packets
|
||||
net.DisableAddEntityHack();
|
||||
|
||||
// Workaround for some servers that don't cast signed bytes to unsigned, before converting them to shorts.
|
||||
if (id < 0) id += 256;
|
||||
if (id >= 0 && id <= 255)
|
||||
|
@ -141,13 +145,11 @@ namespace ClassicalSharp.Network.Protocols {
|
|||
|
||||
void HandleExtRemovePlayerName() {
|
||||
short id = reader.ReadInt16();
|
||||
// Workaround for some servers that don't cast signed bytes to unsigned, before converting them to shorts.
|
||||
if (id < 0) id += 256;
|
||||
|
||||
if (id >= 0 && id <= 255) {
|
||||
game.EntityEvents.RaiseTabEntryRemoved((byte)id);
|
||||
game.TabList.Entries[id] = null;
|
||||
}
|
||||
// Workaround for some servers that don't cast signed bytes to unsigned, before converting them to shorts.
|
||||
if (id < 0) id += 256;
|
||||
if (id >= 0 && id <= 255)
|
||||
net.RemoveTablistEntry((byte)id);
|
||||
}
|
||||
|
||||
void HandleMakeSelection() {
|
||||
|
|
|
@ -172,11 +172,12 @@ namespace ClassicalSharp.Network.Protocols {
|
|||
byte id = reader.ReadUInt8();
|
||||
string name = reader.ReadAsciiString();
|
||||
string skin = name;
|
||||
net.CheckName(id, ref name, ref skin);
|
||||
|
||||
net.CheckName(id, ref name, ref skin);
|
||||
net.AddEntity(id, name, skin, true);
|
||||
// Also workaround for LegendCraft as it declares it supports ExtPlayerList but
|
||||
// doesn't send ExtAddPlayerName packets.
|
||||
|
||||
if (!net.addEntityHack) return;
|
||||
// Workaround for some servers that declare they support ExtPlayerList,
|
||||
// but doesn't send ExtAddPlayerName packets.
|
||||
net.AddTablistEntry(id, name, name, "Players", 0);
|
||||
net.needRemoveNames[id >> 3] |= (byte)(1 << (id & 0x7));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue