Stardew_Valley_Mods/GeneralMods/ModdedUtilitiesNetworking/Framework/Servers/CustomLidgrenServer.cs

230 lines
8.8 KiB
C#
Raw Normal View History

using Lidgren.Network;
using ModdedUtilitiesNetworking.Framework.Messages;
using ModdedUtilitiesNetworking.Framework.Network;
using StardewValley;
using StardewValley.Network;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModdedUtilitiesNetworking.Framework.Servers
{
class CustomLidgrenServer : Server
{
private HashSet<NetConnection> introductionsSent = new HashSet<NetConnection>();
private Bimap<long, NetConnection> peers = new Bimap<long, NetConnection>();
public const int defaultPort = 24642;
private NetServer server;
public override int connectionsCount
{
get
{
if (this.server == null)
return 0;
return this.server.ConnectionsCount;
}
}
public CustomLidgrenServer(IGameServer gameServer)
: base(gameServer)
{
}
public override string getUserName(long farmerId)
{
if (!this.peers.ContainsLeft(farmerId))
return (string)null;
return this.peers[farmerId].RemoteEndPoint.Address.ToString();
}
public override void setPrivacy(ServerPrivacy privacy)
{
}
public override bool canAcceptIPConnections()
{
return true;
}
public override bool connected()
{
return this.server != null;
}
public override void initialize()
{
Console.WriteLine("Starting LAN server");
NetPeerConfiguration config = new NetPeerConfiguration("StardewValley");
config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
config.Port = 24642;
config.ConnectionTimeout = 30f;
config.PingInterval = 5f;
config.MaximumConnections = ModCore.multiplayer.playerLimit * 2;
config.MaximumTransmissionUnit = 1200;
this.server = new NetServer(config);
this.server.Start();
}
public override void stopServer()
{
Console.WriteLine("Stopping LAN server");
this.server.Shutdown("Server shutting down...");
this.server.FlushSendQueue();
this.introductionsSent.Clear();
this.peers.Clear();
}
public override void receiveMessages()
{
NetIncomingMessage netIncomingMessage;
while ((netIncomingMessage = this.server.ReadMessage()) != null)
{
int i = (int)netIncomingMessage.MessageType;
//ModCore.monitor.Log("Message Type: " + i.ToString());
switch (netIncomingMessage.MessageType)
{
case NetIncomingMessageType.WarningMessage:
case NetIncomingMessageType.ErrorMessage:
case NetIncomingMessageType.DebugMessage:
string str = netIncomingMessage.ReadString();
Console.WriteLine("{0}: {1}", (object)netIncomingMessage.MessageType, (object)str);
Game1.debugOutput = str;
break;
case NetIncomingMessageType.DiscoveryRequest:
if (Game1.options.ipConnectionsEnabled)
{
this.sendVersionInfo(netIncomingMessage);
break;
}
break;
case NetIncomingMessageType.StatusChanged:
this.statusChanged(netIncomingMessage);
break;
case NetIncomingMessageType.ConnectionApproval:
if (Game1.options.ipConnectionsEnabled)
{
netIncomingMessage.SenderConnection.Approve();
break;
}
netIncomingMessage.SenderConnection.Deny();
break;
case NetIncomingMessageType.Data:
//ModCore.monitor.Log("GOT DATA~~");
this.parseDataMessageFromClient(netIncomingMessage);
break;
default:
//ModCore.monitor.Log(netIncomingMessage.ToString());
break;
}
this.server.Recycle(netIncomingMessage);
}
foreach (NetConnection netConnection in this.server.Connections)
{
NetConnection conn = netConnection;
if (conn.Status == NetConnectionStatus.Connected && !this.introductionsSent.Contains(conn))
{
this.gameServer.sendAvailableFarmhands("", (Action<OutgoingMessage>)(msg => this.sendMessage(conn, msg)));
this.introductionsSent.Add(conn);
}
}
}
private void sendVersionInfo(NetIncomingMessage message)
{
NetOutgoingMessage message1 = this.server.CreateMessage();
message1.Write(ModCore.multiplayer.protocolVersion);
message1.Write("StardewValley");
this.server.SendDiscoveryResponse(message1, message.SenderEndPoint);
}
private void statusChanged(NetIncomingMessage message)
{
switch ((NetConnectionStatus)message.ReadByte())
{
case NetConnectionStatus.Disconnected:
case NetConnectionStatus.Disconnecting:
if (!this.peers.ContainsRight(message.SenderConnection))
break;
//Forces a de-sync with money.
this.playerDisconnected(this.peers[message.SenderConnection]);
break;
}
}
protected override void playerDisconnected(long disconnectee)
{
this.gameServer.playerDisconnected(disconnectee);
this.introductionsSent.Remove(this.peers[disconnectee]);
this.peers.RemoveLeft(disconnectee);
}
private void parseDataMessageFromClient(NetIncomingMessage dataMsg)
{
//ModCore.monitor.Log("DATA MSG: "+dataMsg.ToString());
NetConnection peer = dataMsg.SenderConnection;
using (IncomingMessage message = new IncomingMessage())
{
using (NetBufferReadStream bufferReadStream = new NetBufferReadStream((NetBuffer)dataMsg))
{
using (BinaryReader reader = new BinaryReader((Stream)bufferReadStream))
{
while ((long)dataMsg.LengthBits - dataMsg.Position >= 8L)
{
message.Read(reader);
int type = message.MessageType;
if (this.peers.ContainsLeft(message.FarmerID) && this.peers[message.FarmerID] == peer)
this.gameServer.processIncomingMessage(message);
else if ((int)message.MessageType == 2)
{
NetFarmerRoot farmer = ModCore.multiplayer.readFarmer(message.Reader);
this.gameServer.checkFarmhandRequest("", farmer, (msg => this.sendMessage(peer, msg)), (Action)(() => this.peers[farmer.Value.UniqueMultiplayerID] = peer));
}
}
}
}
}
}
public override void sendMessage(long peerId, OutgoingMessage message)
{
if (!this.peers.ContainsLeft(peerId))
return;
this.sendMessage(this.peers[peerId], message);
}
protected void sendMessage(NetConnection connection, OutgoingMessage message)
{
NetOutgoingMessage message1 = this.server.CreateMessage();
using (NetBufferWriteStream bufferWriteStream = new NetBufferWriteStream((NetBuffer)message1))
{
using (BinaryWriter writer = new BinaryWriter((Stream)bufferWriteStream)) {
if (message.MessageType < 20)
{
message.Write(writer);
}
else
{
OutgoingMessageBase.WriteFromMessage(message, writer);
}
}
}
int num = (int)this.server.SendMessage(message1, connection, NetDeliveryMethod.ReliableOrdered);
}
public override void setLobbyData(string key, string value)
{
}
}
}