bool NegotiateProtocolExtension()
{
writer.Write(Packet.MakeExtInfo(12).Data);
writer.Write(Packet.MakeExtEntry(CustomBlocksExtName, CustomBlocksExtVersion).Data);
writer.Write(Packet.MakeExtEntry(ClickDistanceExtName, ClickDistanceExtVersion).Data);
writer.Write(Packet.MakeExtEntry(EnvColorsExtName, EnvColorsExtVersion).Data);
writer.Write(Packet.MakeExtEntry(ChangeModelExtName, ChangeModelExtVersion).Data);
writer.Write(Packet.MakeExtEntry(EnvMapAppearanceExtName, EnvMapAppearanceExtVersion).Data);
writer.Write(Packet.MakeExtEntry(HeldBlockExtName, HeldBlockExtVersion).Data);
writer.Write(Packet.MakeExtEntry(ExtPlayerListExtName, ExtPlayerListExtVersion).Data);
writer.Write(Packet.MakeExtEntry(SelectionCuboidExtName, SelectionCuboidExtVersion).Data);
writer.Write(Packet.MakeExtEntry(MessageTypesExtName, MessageTypesExtVersion).Data);
writer.Write(Packet.MakeExtEntry(HackControlExtName, HackControlExtVersion).Data);
writer.Write(Packet.MakeExtEntry(LongerMessagesExtName, LongerMessagesExtVersion).Data);
writer.Write(Packet.MakeExtEntry(FullCP437ExtName, FullCP437ExtVersion).Data);
Logger.Log(LogType.Debug, "Sent ExtInfo and entry packets");
// Expect ExtInfo reply from the client
OpCode extInfoReply = (OpCode)reader.ReadByte();
Logger.Log(LogType.Debug, "Expected: {0} / Received: {1}", OpCode.ExtInfo, extInfoReply);
if (extInfoReply != OpCode.ExtInfo)
{
Logger.Log(LogType.Warning, "Player {0} from {1}: Unexpected ExtInfo reply({2})", Name, IP, extInfoReply);
return(false);
}
//read EXT_INFO from client
ClientName = reader.ReadString();
int expectedEntries = reader.ReadInt16();
// Get all of the ext info packets
bool sendCustomBlockPacket = false;
List <string> clientExts = new List <string>();
for (int i = 0; i < expectedEntries; i++)
{
// Expect ExtEntry replies(0 or more)
OpCode extEntryReply = (OpCode)reader.ReadByte();
Logger.Log(LogType.Debug, "Expected: {0} / Received: {1}", OpCode.ExtEntry, extEntryReply);
if (extEntryReply != OpCode.ExtEntry)
{
Logger.Log(LogType.Warning, "Player {0} from {1}: Unexpected ExtEntry reply({2})", Name, IP, extEntryReply);
return(false);
}
string extName = reader.ReadString();
int extVersion = reader.ReadInt32();
if (extName == CustomBlocksExtName && extVersion == CustomBlocksExtVersion)
{
// Hooray, client supports custom blocks! We still need to check support level.
sendCustomBlockPacket = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == ClickDistanceExtName && extVersion == ClickDistanceExtVersion)
{
SupportsClickDistance = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == EnvColorsExtName && extVersion == EnvColorsExtVersion)
{
SupportsEnvColors = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == ChangeModelExtName && extVersion == ChangeModelExtVersion)
{
SupportsChangeModel = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == EnvMapAppearanceExtName && extVersion == EnvMapAppearanceExtVersion)
{
SupportsEnvMapAppearance = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == HeldBlockExtName && extVersion == HeldBlockExtVersion)
{
SupportsHeldBlock = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == ExtPlayerListExtName && extVersion == ExtPlayerListExtVersion)
{
SupportsExtPlayerList = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == SelectionCuboidExtName && extVersion == SelectionCuboidExtVersion)
{
SupportsSelectionCuboid = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == MessageTypesExtName && extVersion == MessageTypesExtVersion)
{
SupportsMessageTypes = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == EnvWeatherTypeExtName && extVersion == EnvWeatherTypeExtVersion)
{
SupportsEnvWeatherType = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == HackControlExtName && extVersion == HackControlExtVersion)
{
SupportsHackControl = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == LongerMessagesExtName && extVersion == LongerMessagesExtVersion)
{
SupportsLongerMessages = true;
clientExts.Add(extName + " " + extVersion);
}
else if (extName == FullCP437ExtName && extVersion == FullCP437ExtVersion)
{
SupportsFullCP437 = true;
clientExts.Add(extName + " " + extVersion);
}
}
// log client's capabilities
if (clientExts.Count > 0)
{
Logger.Log(LogType.Debug, "Player {0} is using \"{1}\", supporting: {2}",
Name,
ClientName,
clientExts.JoinToString(", "));
}
if (sendCustomBlockPacket)
{
// if client also supports CustomBlockSupportLevel, figure out what level to use
// Send CustomBlockSupportLevel
writer.Write(Packet.MakeCustomBlockSupportLevel(CustomBlocksLevel).Data);
// Expect CustomBlockSupportLevel reply
OpCode customBlockSupportLevelReply = (OpCode)reader.ReadByte();
Logger.Log(LogType.Debug, "Expected: {0} / Received: {1}", OpCode.CustomBlocks, customBlockSupportLevelReply);
if (customBlockSupportLevelReply != OpCode.CustomBlocks)
{
Logger.Log(LogType.Warning, "Player {0} from {1}: Unexpected CustomBlockSupportLevel reply({2})",
Name,
IP,
customBlockSupportLevelReply);
return(false);
}
byte clientLevel = reader.ReadByte();
UsesCustomBlocks = (clientLevel >= CustomBlocksLevel);
}
return(true);
}