LAST UPDATE
This commit is contained in:
@ -39,11 +39,14 @@ namespace CoopClient
|
||||
get { return CurrentHidden; }
|
||||
set
|
||||
{
|
||||
if (value && !CurrentHidden)
|
||||
if (value)
|
||||
{
|
||||
MainScaleForm.CallFunction("hide");
|
||||
if (!CurrentHidden)
|
||||
{
|
||||
MainScaleForm.CallFunction("hide");
|
||||
}
|
||||
}
|
||||
else if (!value && CurrentHidden)
|
||||
else if (CurrentHidden)
|
||||
{
|
||||
MainScaleForm.CallFunction("showFeed");
|
||||
}
|
||||
|
@ -73,8 +73,6 @@ namespace CoopClient
|
||||
public bool VehIsEngineRunning { get; set; }
|
||||
public bool VehAreLightsOn { get; set; }
|
||||
public bool VehAreHighBeamsOn { get; set; }
|
||||
private bool LastVehIsInBurnout = false;
|
||||
public bool VehIsInBurnout { get; set; }
|
||||
public bool VehIsSireneActive { get; set; }
|
||||
private VehicleDoors[] LastVehDoors;
|
||||
public VehicleDoors[] VehDoors { get; set; }
|
||||
@ -95,16 +93,31 @@ namespace CoopClient
|
||||
{
|
||||
if (!LastSyncWasFull)
|
||||
{
|
||||
if (Position != null)
|
||||
{
|
||||
if (PedBlip != null && PedBlip.Exists())
|
||||
{
|
||||
PedBlip.Position = Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
PedBlip = World.CreateBlip(Position);
|
||||
PedBlip.Color = BlipColor.White;
|
||||
PedBlip.Scale = 0.8f;
|
||||
PedBlip.Name = username;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AllDataAvailable = true;
|
||||
}
|
||||
|
||||
#region NOT_IN_RANGE
|
||||
if (!Game.Player.Character.IsInRange(Position, 250f))
|
||||
#region NOT_IN_RANGE OR !AllDataAvailable
|
||||
if (!Game.Player.Character.IsInRange(Position, 500f))
|
||||
{
|
||||
if (MainVehicle != null && MainVehicle.Exists() && MainVehicle.PassengerCount <= 1)
|
||||
if (MainVehicle != null && MainVehicle.Exists() && MainVehicle.PassengerCount == 0)
|
||||
{
|
||||
MainVehicle.Delete();
|
||||
MainVehicle = null;
|
||||
@ -118,17 +131,17 @@ namespace CoopClient
|
||||
|
||||
if (username != null)
|
||||
{
|
||||
if (PedBlip == null || !PedBlip.Exists())
|
||||
if (PedBlip != null && PedBlip.Exists())
|
||||
{
|
||||
PedBlip.Position = Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
PedBlip = World.CreateBlip(Position);
|
||||
PedBlip.Color = BlipColor.White;
|
||||
PedBlip.Scale = 0.8f;
|
||||
PedBlip.Name = username;
|
||||
}
|
||||
else
|
||||
{
|
||||
PedBlip.Position = Position;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -136,11 +149,6 @@ namespace CoopClient
|
||||
#endregion
|
||||
|
||||
#region IS_IN_RANGE
|
||||
if (PedBlip != null && PedBlip.Exists())
|
||||
{
|
||||
PedBlip.Delete();
|
||||
}
|
||||
|
||||
bool characterExist = Character != null && Character.Exists();
|
||||
|
||||
if (!characterExist)
|
||||
@ -405,19 +413,6 @@ namespace CoopClient
|
||||
|
||||
LastVehDoors = VehDoors;
|
||||
}
|
||||
|
||||
if (VehIsInBurnout && !LastVehIsInBurnout)
|
||||
{
|
||||
Function.Call(Hash.SET_VEHICLE_BURNOUT, MainVehicle, true);
|
||||
Function.Call(Hash.TASK_VEHICLE_TEMP_ACTION, Character, MainVehicle, 23, 120000); // 30 - burnout
|
||||
}
|
||||
else if (!VehIsInBurnout && LastVehIsInBurnout)
|
||||
{
|
||||
Function.Call(Hash.SET_VEHICLE_BURNOUT, MainVehicle, false);
|
||||
Function.Call(Hash.CLEAR_PED_TASKS_IMMEDIATELY, Character); // Buggy but we need this to stop this burnout
|
||||
}
|
||||
|
||||
LastVehIsInBurnout = VehIsInBurnout;
|
||||
}
|
||||
|
||||
if (VehicleSteeringAngle != MainVehicle.SteeringAngle)
|
||||
@ -426,7 +421,7 @@ namespace CoopClient
|
||||
}
|
||||
|
||||
// Good enough for now, but we need to create a better sync
|
||||
if ((CurrentVehicleSpeed > 0.2f || VehIsInBurnout) && MainVehicle.IsInRange(VehiclePosition, 7.0f))
|
||||
if (CurrentVehicleSpeed > 0.05f && MainVehicle.IsInRange(VehiclePosition, 7.0f))
|
||||
{
|
||||
int forceMultiplier = (Game.Player.Character.IsInVehicle() && MainVehicle.IsTouching(Game.Player.Character.CurrentVehicle)) ? 1 : 3;
|
||||
|
||||
@ -597,6 +592,12 @@ namespace CoopClient
|
||||
|
||||
private bool CreateCharacter(string username)
|
||||
{
|
||||
if (PedBlip != null && PedBlip.Exists())
|
||||
{
|
||||
PedBlip.Delete();
|
||||
PedBlip = null;
|
||||
}
|
||||
|
||||
LastModelHash = ModelHash;
|
||||
LastProps = Props;
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace CoopClient
|
||||
|
||||
private bool GameLoaded = false;
|
||||
|
||||
public static readonly string CurrentModVersion = "V0_6_0";
|
||||
public static readonly string CurrentModVersion = "V0_7_0";
|
||||
|
||||
public static bool ShareNpcsWithPlayers = false;
|
||||
public static bool DisableTraffic = false;
|
||||
@ -33,7 +33,7 @@ namespace CoopClient
|
||||
|
||||
public static Chat MainChat = new Chat();
|
||||
|
||||
public static long LocalPlayerID = 0;
|
||||
public static long LocalClientID = 0;
|
||||
public static readonly Dictionary<long, EntitiesPlayer> Players = new Dictionary<long, EntitiesPlayer>();
|
||||
public static readonly Dictionary<long, EntitiesNpc> Npcs = new Dictionary<long, EntitiesNpc>();
|
||||
|
||||
@ -291,7 +291,6 @@ namespace CoopClient
|
||||
DebugSyncPed.VehIsEngineRunning = (flags.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
|
||||
DebugSyncPed.VehAreLightsOn = (flags.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
|
||||
DebugSyncPed.VehAreHighBeamsOn = (flags.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
|
||||
DebugSyncPed.VehIsInBurnout = (flags.Value & (byte)VehicleDataFlags.IsInBurnout) > 0;
|
||||
DebugSyncPed.VehIsSireneActive = (flags.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
|
||||
DebugSyncPed.VehicleDead = (flags.Value & (byte)VehicleDataFlags.IsDead) > 0;
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace CoopClient
|
||||
if (IsOnServer())
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
|
||||
new PlayerDisconnectPacket() { Player = Main.LocalPlayerID }.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
new PlayerDisconnectPacket() { ID = Main.LocalClientID }.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered);
|
||||
Client.FlushSendQueue();
|
||||
|
||||
@ -107,7 +107,7 @@ namespace CoopClient
|
||||
remoteHailMessagePacket.NetIncomingMessageToPacket(message.SenderConnection.RemoteHailMessage);
|
||||
|
||||
HandshakePacket handshakePacket = (HandshakePacket)remoteHailMessagePacket;
|
||||
Main.LocalPlayerID = handshakePacket.ID;
|
||||
Main.LocalClientID = handshakePacket.ID;
|
||||
Main.NpcsAllowed = handshakePacket.NpcsAllowed;
|
||||
|
||||
Main.CleanUp();
|
||||
@ -122,7 +122,7 @@ namespace CoopClient
|
||||
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
|
||||
new PlayerConnectPacket()
|
||||
{
|
||||
Player = Main.LocalPlayerID,
|
||||
ID = Main.LocalClientID,
|
||||
SocialClubName = string.Empty,
|
||||
Username = string.Empty
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
@ -211,6 +211,11 @@ namespace CoopClient
|
||||
packet.NetIncomingMessageToPacket(message);
|
||||
FullSyncNpcVeh((FullSyncNpcVehPacket)packet);
|
||||
break;
|
||||
case (byte)PacketTypes.SuperLightSyncPlayerPacket:
|
||||
packet = new SuperLightSyncPlayerPacket();
|
||||
packet.NetIncomingMessageToPacket(message);
|
||||
SuperLightSyncPlayer((SuperLightSyncPlayerPacket)packet);
|
||||
break;
|
||||
case (byte)PacketTypes.ChatMessagePacket:
|
||||
packet = new ChatMessagePacket();
|
||||
packet.NetIncomingMessageToPacket(message);
|
||||
@ -252,14 +257,14 @@ namespace CoopClient
|
||||
LastUpdateReceived = Environment.TickCount
|
||||
};
|
||||
|
||||
Main.Players.Add(packet.Player, player);
|
||||
Main.Players.Add(packet.ID, player);
|
||||
}
|
||||
|
||||
private void PlayerDisconnect(PlayerDisconnectPacket packet)
|
||||
{
|
||||
if (Main.Players.ContainsKey(packet.Player))
|
||||
if (Main.Players.ContainsKey(packet.ID))
|
||||
{
|
||||
EntitiesPlayer player = Main.Players[packet.Player];
|
||||
EntitiesPlayer player = Main.Players[packet.ID];
|
||||
if (player.Character != null && player.Character.Exists())
|
||||
{
|
||||
player.Character.Kill();
|
||||
@ -268,18 +273,15 @@ namespace CoopClient
|
||||
|
||||
player.PedBlip?.Delete();
|
||||
|
||||
Main.Players.Remove(packet.Player);
|
||||
Main.Players.Remove(packet.ID);
|
||||
}
|
||||
}
|
||||
|
||||
private void FullSyncPlayer(FullSyncPlayerPacket packet)
|
||||
{
|
||||
if (Main.Players.ContainsKey(packet.Extra.Player))
|
||||
if (Main.Players.ContainsKey(packet.Extra.ID))
|
||||
{
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.Player];
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.ID];
|
||||
|
||||
player.ModelHash = packet.ModelHash;
|
||||
player.Props = packet.Props;
|
||||
@ -298,17 +300,17 @@ namespace CoopClient
|
||||
player.IsRagdoll = (packet.Flag.Value & (byte)PedDataFlags.IsRagdoll) > 0;
|
||||
player.IsOnFire = (packet.Flag.Value & (byte)PedDataFlags.IsOnFire) > 0;
|
||||
player.IsInVehicle = (packet.Flag.Value & (byte)PedDataFlags.IsInVehicle) > 0;
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
}
|
||||
}
|
||||
|
||||
private void FullSyncPlayerVeh(FullSyncPlayerVehPacket packet)
|
||||
{
|
||||
if (Main.Players.ContainsKey(packet.Extra.Player))
|
||||
if (Main.Players.ContainsKey(packet.Extra.ID))
|
||||
{
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.Player];
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.ID];
|
||||
|
||||
player.ModelHash = packet.ModelHash;
|
||||
player.Props = packet.Props;
|
||||
@ -330,20 +332,19 @@ namespace CoopClient
|
||||
player.VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
|
||||
player.VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
|
||||
player.VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
|
||||
player.VehIsInBurnout = (packet.Flag.Value & (byte)VehicleDataFlags.IsInBurnout) > 0;
|
||||
player.VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
|
||||
player.VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0;
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
}
|
||||
}
|
||||
|
||||
private void LightSyncPlayer(LightSyncPlayerPacket packet)
|
||||
{
|
||||
if (Main.Players.ContainsKey(packet.Extra.Player))
|
||||
if (Main.Players.ContainsKey(packet.Extra.ID))
|
||||
{
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.Player];
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.ID];
|
||||
|
||||
player.Health = packet.Extra.Health;
|
||||
player.Position = packet.Extra.Position.ToVector();
|
||||
@ -360,17 +361,17 @@ namespace CoopClient
|
||||
player.IsRagdoll = (packet.Flag.Value & (byte)PedDataFlags.IsRagdoll) > 0;
|
||||
player.IsOnFire = (packet.Flag.Value & (byte)PedDataFlags.IsOnFire) > 0;
|
||||
player.IsInVehicle = (packet.Flag.Value & (byte)PedDataFlags.IsInVehicle) > 0;
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
}
|
||||
}
|
||||
|
||||
private void LightSyncPlayerVeh(LightSyncPlayerVehPacket packet)
|
||||
{
|
||||
if (Main.Players.ContainsKey(packet.Extra.Player))
|
||||
if (Main.Players.ContainsKey(packet.Extra.ID))
|
||||
{
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.Player];
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.ID];
|
||||
|
||||
player.Health = packet.Extra.Health;
|
||||
player.Position = packet.Extra.Position.ToVector();
|
||||
@ -386,9 +387,25 @@ namespace CoopClient
|
||||
player.VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
|
||||
player.VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
|
||||
player.VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
|
||||
player.VehIsInBurnout = (packet.Flag.Value & (byte)VehicleDataFlags.IsInBurnout) > 0;
|
||||
player.VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
|
||||
player.VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0;
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
}
|
||||
}
|
||||
|
||||
private void SuperLightSyncPlayer(SuperLightSyncPlayerPacket packet)
|
||||
{
|
||||
if (Main.Players.ContainsKey(packet.Extra.ID))
|
||||
{
|
||||
EntitiesPlayer player = Main.Players[packet.Extra.ID];
|
||||
|
||||
player.Health = packet.Extra.Health;
|
||||
player.Position = packet.Extra.Position.ToVector();
|
||||
|
||||
player.Latency = packet.Extra.Latency;
|
||||
player.LastUpdateReceived = Environment.TickCount;
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,7 +536,6 @@ namespace CoopClient
|
||||
npc.VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
|
||||
npc.VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
|
||||
npc.VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
|
||||
npc.VehIsInBurnout = (packet.Flag.Value & (byte)VehicleDataFlags.IsInBurnout) > 0;
|
||||
npc.VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
|
||||
npc.VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0;
|
||||
}
|
||||
@ -548,7 +564,6 @@ namespace CoopClient
|
||||
VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0,
|
||||
VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0,
|
||||
VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0,
|
||||
VehIsInBurnout = (packet.Flag.Value & (byte)VehicleDataFlags.IsInBurnout) > 0,
|
||||
VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0,
|
||||
VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0
|
||||
});
|
||||
@ -577,7 +592,7 @@ namespace CoopClient
|
||||
{
|
||||
Extra = new PlayerPacket()
|
||||
{
|
||||
Player = Main.LocalPlayerID,
|
||||
ID = Main.LocalClientID,
|
||||
Health = player.Health,
|
||||
Position = player.Position.ToLVector()
|
||||
},
|
||||
@ -610,7 +625,7 @@ namespace CoopClient
|
||||
{
|
||||
Extra = new PlayerPacket()
|
||||
{
|
||||
Player = Main.LocalPlayerID,
|
||||
ID = Main.LocalClientID,
|
||||
Health = player.Health,
|
||||
Position = player.Position.ToLVector()
|
||||
},
|
||||
@ -643,7 +658,7 @@ namespace CoopClient
|
||||
{
|
||||
Extra = new PlayerPacket()
|
||||
{
|
||||
Player = Main.LocalPlayerID,
|
||||
ID = Main.LocalClientID,
|
||||
Health = player.Health,
|
||||
Position = player.Position.ToLVector()
|
||||
},
|
||||
@ -663,7 +678,7 @@ namespace CoopClient
|
||||
{
|
||||
Extra = new PlayerPacket()
|
||||
{
|
||||
Player = Main.LocalPlayerID,
|
||||
ID = Main.LocalClientID,
|
||||
Health = player.Health,
|
||||
Position = player.Position.ToLVector()
|
||||
},
|
||||
@ -698,7 +713,7 @@ namespace CoopClient
|
||||
{
|
||||
new FullSyncNpcPacket()
|
||||
{
|
||||
ID = Main.LocalPlayerID + npc.Handle,
|
||||
ID = Main.LocalClientID + npc.Handle,
|
||||
ModelHash = npc.Model.Hash,
|
||||
Props = Util.GetPedProps(npc),
|
||||
Health = npc.Health,
|
||||
@ -728,7 +743,7 @@ namespace CoopClient
|
||||
|
||||
new FullSyncNpcVehPacket()
|
||||
{
|
||||
ID = Main.LocalPlayerID + npc.Handle,
|
||||
ID = Main.LocalClientID + npc.Handle,
|
||||
ModelHash = npc.Model.Hash,
|
||||
Props = Util.GetPedProps(npc),
|
||||
Health = npc.Health,
|
||||
|
@ -123,6 +123,7 @@ namespace CoopClient
|
||||
FullSyncPlayerVehPacket,
|
||||
LightSyncPlayerPacket,
|
||||
LightSyncPlayerVehPacket,
|
||||
SuperLightSyncPlayerPacket,
|
||||
FullSyncNpcPacket,
|
||||
FullSyncNpcVehPacket,
|
||||
ChatMessagePacket,
|
||||
@ -151,9 +152,8 @@ namespace CoopClient
|
||||
IsEngineRunning = 1 << 2,
|
||||
AreLightsOn = 1 << 3,
|
||||
AreHighBeamsOn = 1 << 4,
|
||||
IsInBurnout = 1 << 5,
|
||||
IsSirenActive = 1 << 6,
|
||||
IsDead = 1 << 7
|
||||
IsSirenActive = 1 << 5,
|
||||
IsDead = 1 << 6
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
@ -242,7 +242,7 @@ namespace CoopClient
|
||||
class PlayerConnectPacket : Packet
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public long Player { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
[ProtoMember(2)]
|
||||
public string SocialClubName { get; set; }
|
||||
@ -266,7 +266,7 @@ namespace CoopClient
|
||||
|
||||
PlayerConnectPacket data = CoopSerializer.Deserialize<PlayerConnectPacket>(message.ReadBytes(len));
|
||||
|
||||
Player = data.Player;
|
||||
ID = data.ID;
|
||||
SocialClubName = data.SocialClubName;
|
||||
Username = data.Username;
|
||||
}
|
||||
@ -276,7 +276,7 @@ namespace CoopClient
|
||||
class PlayerDisconnectPacket : Packet
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public long Player { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
|
||||
{
|
||||
@ -294,7 +294,7 @@ namespace CoopClient
|
||||
|
||||
PlayerDisconnectPacket data = CoopSerializer.Deserialize<PlayerDisconnectPacket>(message.ReadBytes(len));
|
||||
|
||||
Player = data.Player;
|
||||
ID = data.ID;
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,7 +302,7 @@ namespace CoopClient
|
||||
struct PlayerPacket
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public long Player { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
[ProtoMember(2)]
|
||||
public int Health { get; set; }
|
||||
@ -562,6 +562,32 @@ namespace CoopClient
|
||||
}
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class SuperLightSyncPlayerPacket : Packet
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public PlayerPacket Extra { get; set; }
|
||||
|
||||
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
|
||||
{
|
||||
message.Write((byte)PacketTypes.SuperLightSyncPlayerPacket);
|
||||
|
||||
byte[] result = CoopSerializer.Serialize(this);
|
||||
|
||||
message.Write(result.Length);
|
||||
message.Write(result);
|
||||
}
|
||||
|
||||
public override void NetIncomingMessageToPacket(NetIncomingMessage message)
|
||||
{
|
||||
int len = message.ReadInt32();
|
||||
|
||||
SuperLightSyncPlayerPacket data = CoopSerializer.Deserialize<SuperLightSyncPlayerPacket>(message.ReadBytes(len));
|
||||
|
||||
Extra = data.Extra;
|
||||
}
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class ChatMessagePacket : Packet
|
||||
{
|
||||
|
@ -195,11 +195,6 @@ namespace CoopClient
|
||||
flags |= (byte)VehicleDataFlags.AreHighBeamsOn;
|
||||
}
|
||||
|
||||
if (veh.IsInBurnout)
|
||||
{
|
||||
flags |= (byte)VehicleDataFlags.IsInBurnout;
|
||||
}
|
||||
|
||||
if (veh.IsSirenActive)
|
||||
{
|
||||
flags |= (byte)VehicleDataFlags.IsSirenActive;
|
||||
|
@ -9,26 +9,26 @@ namespace FirstGameMode
|
||||
[Command("hello")]
|
||||
public static void HelloCommand(CommandContext ctx)
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, "Hello " + ctx.Player.Username + " :)");
|
||||
ctx.Client.SendChatMessage("Hello " + ctx.Client.Player.Username + " :)");
|
||||
}
|
||||
|
||||
[Command("inrange")]
|
||||
public static void InRangeCommand(CommandContext ctx)
|
||||
{
|
||||
if (ctx.Player.IsInRangeOf(new LVector3(0f, 0f, 75f), 7f))
|
||||
if (ctx.Client.Player.IsInRangeOf(new LVector3(0f, 0f, 75f), 7f))
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, "You are in range! :)");
|
||||
ctx.Client.SendChatMessage("You are in range! :)");
|
||||
}
|
||||
else
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, "You are not in range! :(");
|
||||
ctx.Client.SendChatMessage("You are not in range! :(");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("online")]
|
||||
public static void OnlineCommand(CommandContext ctx)
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, API.GetAllPlayersCount() + " player online!");
|
||||
ctx.Client.SendChatMessage(API.GetAllClientsCount() + " player online!");
|
||||
}
|
||||
|
||||
[Command("kick")]
|
||||
@ -36,11 +36,11 @@ namespace FirstGameMode
|
||||
{
|
||||
if (ctx.Args.Length < 2)
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, "Please use \"/kick <USERNAME> <REASON>\"");
|
||||
ctx.Client.SendChatMessage("Please use \"/kick <USERNAME> <REASON>\"");
|
||||
return;
|
||||
}
|
||||
|
||||
API.KickPlayerByUsername(ctx.Args[0], ctx.Args.Skip(1).ToArray());
|
||||
ctx.Client.Kick(ctx.Args.Skip(1).ToArray());
|
||||
}
|
||||
|
||||
[Command("setweather")]
|
||||
@ -50,16 +50,16 @@ namespace FirstGameMode
|
||||
|
||||
if (ctx.Args.Length < 3)
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, "Please use \"/setweather <HOURS> <MINUTES> <SECONDS>\"");
|
||||
ctx.Client.SendChatMessage("Please use \"/setweather <HOURS> <MINUTES> <SECONDS>\"");
|
||||
return;
|
||||
}
|
||||
else if (!int.TryParse(ctx.Args[0], out hours) || !int.TryParse(ctx.Args[1], out minutes) || !int.TryParse(ctx.Args[2], out seconds))
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, "Please use \"/setweather <NUMBER> <NUMBER> <NUMBER>\"");
|
||||
ctx.Client.SendChatMessage("Please use \"/setweather <NUMBER> <NUMBER> <NUMBER>\"");
|
||||
return;
|
||||
}
|
||||
|
||||
API.SendNativeCallToPlayer(ctx.Player.Username, 0x47C3B5848C3E45D8, hours, minutes, seconds);
|
||||
ctx.Client.SendNativeCall(0x47C3B5848C3E45D8, hours, minutes, seconds);
|
||||
}
|
||||
|
||||
[Command("upp")]
|
||||
|
@ -3,7 +3,6 @@ using System.ComponentModel;
|
||||
using System.Timers;
|
||||
|
||||
using CoopServer;
|
||||
using CoopServer.Entities;
|
||||
|
||||
namespace FirstGameMode
|
||||
{
|
||||
@ -30,17 +29,17 @@ namespace FirstGameMode
|
||||
|
||||
public static void RunningCommand(CommandContext ctx)
|
||||
{
|
||||
API.SendChatMessageToPlayer(ctx.Player.Username, "Server has been running for: " + RunningSince + " seconds!");
|
||||
ctx.Client.SendChatMessage("Server has been running for: " + RunningSince + " seconds!");
|
||||
}
|
||||
|
||||
public static void OnPlayerConnected(EntitiesPlayer player)
|
||||
public static void OnPlayerConnected(Client client)
|
||||
{
|
||||
API.SendChatMessageToAll("Player " + player.Username + " connected!");
|
||||
API.SendChatMessageToAll("Player " + client.Player.Username + " connected!");
|
||||
}
|
||||
|
||||
public static void OnPlayerDisconnected(EntitiesPlayer player)
|
||||
public static void OnPlayerDisconnected(Client client)
|
||||
{
|
||||
API.SendChatMessageToAll("Player " + player.Username + " disconnected!");
|
||||
API.SendChatMessageToAll("Player " + client.Player.Username + " disconnected!");
|
||||
}
|
||||
|
||||
public static void OnChatMessage(string username, string message, CancelEventArgs e)
|
||||
@ -49,21 +48,25 @@ namespace FirstGameMode
|
||||
|
||||
if (message.StartsWith("EASTEREGG"))
|
||||
{
|
||||
API.SendChatMessageToPlayer(username, "You found the EASTEREGG! *-*");
|
||||
Client client;
|
||||
if ((client = API.GetClientByUsername(username)) != null)
|
||||
{
|
||||
client.SendChatMessage("You found the EASTEREGG! *-*");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
API.SendChatMessageToAll(message, username);
|
||||
}
|
||||
|
||||
public static void OnPlayerPositionUpdate(EntitiesPlayer player)
|
||||
public static void OnPlayerPositionUpdate(Client client)
|
||||
{
|
||||
if (ShowPlayerPosition)
|
||||
{
|
||||
if (!SecretLocation.Contains(player.Username) && player.IsInRangeOf(new LVector3(0, 0, 75), 7f))
|
||||
if (!SecretLocation.Contains(client.Player.Username) && client.Player.IsInRangeOf(new LVector3(0, 0, 75), 7f))
|
||||
{
|
||||
API.SendChatMessageToPlayer(player.Username, "Hey! you find this secret location!");
|
||||
SecretLocation.Add(player.Username);
|
||||
client.SendChatMessage("Hey! you find this secret location!");
|
||||
SecretLocation.Add(client.Player.Username);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
14
GTACoop.sln
14
GTACoop.sln
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31423.177
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31605.320
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoopServer", "Server\CoopServer.csproj", "{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}"
|
||||
EndProject
|
||||
@ -9,16 +9,26 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoopClient", "Client\CoopCl
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{84AB99D9-5E00-4CA2-B1DD-56B8419AAD24}.Release|x64.Build.0 = Release|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
|
60
MasterServer/Logging.cs
Normal file
60
MasterServer/Logging.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace MasterServer
|
||||
{
|
||||
class Logging
|
||||
{
|
||||
private static readonly object Lock = new();
|
||||
|
||||
public static void Info(string message)
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
string msg = string.Format("[{0}] [INFO] {1}", Date(), message);
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
|
||||
using StreamWriter sw = new("log.txt", true);
|
||||
sw.WriteLine(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Warning(string message)
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
string msg = string.Format("[{0}] [WARNING] {1}", Date(), message);
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
|
||||
using StreamWriter sw = new("log.txt", true);
|
||||
sw.WriteLine(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Error(string message)
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
string msg = string.Format("[{0}] [ERROR] {1}", Date(), message);
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
|
||||
using StreamWriter sw = new("log.txt", true);
|
||||
sw.WriteLine(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static string Date()
|
||||
{
|
||||
return DateTime.Now.ToString();
|
||||
}
|
||||
}
|
||||
}
|
8
MasterServer/MasterServer.csproj
Normal file
8
MasterServer/MasterServer.csproj
Normal file
@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
89
MasterServer/Program.cs
Normal file
89
MasterServer/Program.cs
Normal file
@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace MasterServer
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static readonly List<Server> Servers = new();
|
||||
static readonly Dictionary<string, int> SpamSecurity = new();
|
||||
|
||||
static void Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.Title = "MasterServer v0.1.0";
|
||||
|
||||
Logging.Info("Trying to start the socket...");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error(e.Message.ToString());
|
||||
}
|
||||
|
||||
Listen();
|
||||
}
|
||||
|
||||
static void Listen()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// 16 milliseconds to sleep to reduce CPU usage
|
||||
Thread.Sleep(1000 / 60);
|
||||
}
|
||||
}
|
||||
|
||||
#region ===== FUNCTIONS =====
|
||||
static bool CheckSpam(string address)
|
||||
{
|
||||
return SpamSecurity.TryGetValue(address, out int lastCheck) && (Environment.TickCount - lastCheck) < 10000;
|
||||
}
|
||||
|
||||
static Server GetServerForClient()
|
||||
{
|
||||
return Servers.Find(x => x.Players < x.MaxPlayers);
|
||||
}
|
||||
|
||||
static bool AddServer(Server server)
|
||||
{
|
||||
if (Servers.Exists(x => x.Address == server.Address))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Servers.Add(server);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error(e.Message.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool RemoveServer(Server server)
|
||||
{
|
||||
if (!Servers.Exists(x => x.Address == server.Address))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Servers.Remove(server);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error(e.Message.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
9
MasterServer/Server.cs
Normal file
9
MasterServer/Server.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace MasterServer
|
||||
{
|
||||
struct Server
|
||||
{
|
||||
public string Address { get; set; }
|
||||
public int Players { get; set; }
|
||||
public int MaxPlayers { get; set; }
|
||||
}
|
||||
}
|
54
Server/Client.cs
Normal file
54
Server/Client.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace CoopServer
|
||||
{
|
||||
public class Client
|
||||
{
|
||||
public long ID = 0;
|
||||
public float Latency = 0.0f;
|
||||
public PlayerData Player;
|
||||
|
||||
public void Kick(string[] reason)
|
||||
{
|
||||
Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID).Disconnect(string.Join(" ", reason));
|
||||
}
|
||||
|
||||
public void SendChatMessage(string message, string from = "Server")
|
||||
{
|
||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID);
|
||||
|
||||
ChatMessagePacket packet = new()
|
||||
{
|
||||
Username = from,
|
||||
Message = message
|
||||
};
|
||||
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
public void SendNativeCall(ulong hash, params object[] args)
|
||||
{
|
||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == ID);
|
||||
|
||||
List<NativeArgument> arguments = Util.ParseNativeArguments(args);
|
||||
if (arguments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NativeCallPacket packet = new()
|
||||
{
|
||||
Hash = hash,
|
||||
Args = arguments
|
||||
};
|
||||
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="protobuf-net" Version="2.4.6" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -66,6 +66,7 @@ namespace CoopServer
|
||||
FullSyncPlayerVehPacket,
|
||||
LightSyncPlayerPacket,
|
||||
LightSyncPlayerVehPacket,
|
||||
SuperLightSyncPlayerPacket,
|
||||
FullSyncNpcPacket,
|
||||
FullSyncNpcVehPacket,
|
||||
ChatMessagePacket,
|
||||
@ -94,9 +95,8 @@ namespace CoopServer
|
||||
IsEngineRunning = 1 << 2,
|
||||
AreLightsOn = 1 << 3,
|
||||
AreHighBeamsOn = 1 << 4,
|
||||
IsInBurnout = 1 << 5,
|
||||
IsSirenActive = 1 << 6,
|
||||
IsDead = 1 << 7
|
||||
IsSirenActive = 1 << 5,
|
||||
IsDead = 1 << 6
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
@ -175,7 +175,7 @@ namespace CoopServer
|
||||
class PlayerConnectPacket : Packet
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public long Player { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
[ProtoMember(2)]
|
||||
public string SocialClubName { get; set; }
|
||||
@ -199,7 +199,7 @@ namespace CoopServer
|
||||
|
||||
PlayerConnectPacket data = CoopSerializer.Deserialize<PlayerConnectPacket>(message.ReadBytes(len));
|
||||
|
||||
Player = data.Player;
|
||||
ID = data.ID;
|
||||
SocialClubName = data.SocialClubName;
|
||||
Username = data.Username;
|
||||
}
|
||||
@ -209,7 +209,7 @@ namespace CoopServer
|
||||
class PlayerDisconnectPacket : Packet
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public long Player { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
|
||||
{
|
||||
@ -227,7 +227,7 @@ namespace CoopServer
|
||||
|
||||
PlayerDisconnectPacket data = CoopSerializer.Deserialize<PlayerDisconnectPacket>(message.ReadBytes(len));
|
||||
|
||||
Player = data.Player;
|
||||
ID = data.ID;
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ namespace CoopServer
|
||||
struct PlayerPacket
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public long Player { get; set; }
|
||||
public long ID { get; set; }
|
||||
|
||||
[ProtoMember(2)]
|
||||
public int Health { get; set; }
|
||||
@ -495,6 +495,32 @@ namespace CoopServer
|
||||
}
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class SuperLightSyncPlayerPacket : Packet
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public PlayerPacket Extra { get; set; }
|
||||
|
||||
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
|
||||
{
|
||||
message.Write((byte)PacketTypes.SuperLightSyncPlayerPacket);
|
||||
|
||||
byte[] result = CoopSerializer.Serialize(this);
|
||||
|
||||
message.Write(result.Length);
|
||||
message.Write(result);
|
||||
}
|
||||
|
||||
public override void NetIncomingMessageToPacket(NetIncomingMessage message)
|
||||
{
|
||||
int len = message.ReadInt32();
|
||||
|
||||
SuperLightSyncPlayerPacket data = CoopSerializer.Deserialize<SuperLightSyncPlayerPacket>(message.ReadBytes(len));
|
||||
|
||||
Extra = data.Extra;
|
||||
}
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class ChatMessagePacket : Packet
|
||||
{
|
||||
|
@ -1,12 +1,11 @@
|
||||
namespace CoopServer.Entities
|
||||
namespace CoopServer
|
||||
{
|
||||
public class EntitiesPlayer
|
||||
public struct PlayerData
|
||||
{
|
||||
public string SocialClubName { get; set; }
|
||||
public string Username { get; set; }
|
||||
public float Latency { get; set; }
|
||||
private LVector3 LastPosition = new();
|
||||
private LVector3 CurrentPosition = new();
|
||||
private LVector3 LastPosition { get; set; }
|
||||
private LVector3 CurrentPosition { get; set; }
|
||||
public LVector3 Position
|
||||
{
|
||||
get
|
336
Server/Server.cs
336
Server/Server.cs
@ -2,26 +2,16 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Text;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Lidgren.Network;
|
||||
|
||||
using CoopServer.Entities;
|
||||
|
||||
namespace CoopServer
|
||||
{
|
||||
class IpInfo
|
||||
{
|
||||
public string Country { get; set; }
|
||||
}
|
||||
|
||||
class Server
|
||||
{
|
||||
public static readonly string CurrentModVersion = "V0_6_0";
|
||||
public static readonly string CurrentModVersion = "V0_7_0";
|
||||
|
||||
public static readonly Settings MainSettings = Util.Read<Settings>("CoopSettings.xml");
|
||||
private readonly Blocklist MainBlocklist = Util.Read<Blocklist>("Blocklist.xml");
|
||||
@ -29,10 +19,10 @@ namespace CoopServer
|
||||
|
||||
public static NetServer MainNetServer;
|
||||
|
||||
public static readonly Dictionary<long, EntitiesPlayer> Players = new();
|
||||
|
||||
public static ServerScript GameMode;
|
||||
public static readonly Dictionary<Command, Action<CommandContext>> Commands = new Dictionary<Command, Action<CommandContext>>();
|
||||
public static Dictionary<Command, Action<CommandContext>> Commands;
|
||||
|
||||
public static readonly List<Client> Clients = new();
|
||||
|
||||
public Server()
|
||||
{
|
||||
@ -67,67 +57,6 @@ namespace CoopServer
|
||||
}
|
||||
}
|
||||
|
||||
if (MainSettings.AnnounceSelf)
|
||||
{
|
||||
#region -- MASTERSERVER --
|
||||
new Thread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpClient httpClient = new();
|
||||
|
||||
IpInfo info;
|
||||
|
||||
try
|
||||
{
|
||||
string data = await httpClient.GetStringAsync("https://ipinfo.io/json");
|
||||
|
||||
info = JsonConvert.DeserializeObject<IpInfo>(data);
|
||||
}
|
||||
catch
|
||||
{
|
||||
info = new() { Country = "?" };
|
||||
}
|
||||
|
||||
bool responseError = false;
|
||||
|
||||
while (!responseError)
|
||||
{
|
||||
string msg =
|
||||
"{ " +
|
||||
"\"port\": \"" + MainSettings.ServerPort + "\", " +
|
||||
"\"name\": \"" + MainSettings.ServerName + "\", " +
|
||||
"\"version\": \"" + CurrentModVersion.Replace("_", ".") + "\", " +
|
||||
"\"players\": \"" + MainNetServer.ConnectionsCount + "\", " +
|
||||
"\"maxPlayers\": \"" + MainSettings.MaxPlayers + "\", " +
|
||||
"\"allowlist\": \"" + MainSettings.Allowlist + "\", " +
|
||||
"\"country\": \"" + info.Country + "\"" +
|
||||
" }";
|
||||
|
||||
HttpResponseMessage response = await httpClient.PostAsync(MainSettings.MasterServer, new StringContent(msg, Encoding.UTF8, "application/json"));
|
||||
|
||||
string responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
if (responseContent != "OK!")
|
||||
{
|
||||
Logging.Error(responseContent);
|
||||
responseError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sleep for 12.5s
|
||||
Thread.Sleep(12500);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Error(ex.Message);
|
||||
}
|
||||
}).Start();
|
||||
#endregion
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(MainSettings.GameMode))
|
||||
{
|
||||
try
|
||||
@ -145,6 +74,8 @@ namespace CoopServer
|
||||
}
|
||||
else
|
||||
{
|
||||
Commands = new();
|
||||
|
||||
GameMode = Activator.CreateInstance(enumerable.ToArray()[0]) as ServerScript;
|
||||
if (GameMode == null)
|
||||
{
|
||||
@ -169,7 +100,7 @@ namespace CoopServer
|
||||
{
|
||||
Logging.Info("Listening for clients");
|
||||
|
||||
while (!Console.KeyAvailable || Console.ReadKey().Key != ConsoleKey.Escape)
|
||||
while (true)
|
||||
{
|
||||
// 16 milliseconds to sleep to reduce CPU usage
|
||||
Thread.Sleep(1000 / 60);
|
||||
@ -178,15 +109,13 @@ namespace CoopServer
|
||||
|
||||
while ((message = MainNetServer.ReadMessage()) != null)
|
||||
{
|
||||
long player;
|
||||
|
||||
switch (message.MessageType)
|
||||
{
|
||||
case NetIncomingMessageType.ConnectionApproval:
|
||||
Logging.Info("New incoming connection from: " + message.SenderConnection.RemoteEndPoint.ToString());
|
||||
if (message.ReadByte() != (byte)PacketTypes.HandshakePacket)
|
||||
{
|
||||
Logging.Info(string.Format("Player with IP {0} blocked, reason: Wrong packet!", message.SenderConnection.RemoteEndPoint.ToString()));
|
||||
Logging.Info(string.Format("Player with IP {0} blocked, reason: Wrong packet!", message.SenderConnection.RemoteEndPoint.Address.ToString()));
|
||||
message.SenderConnection.Deny("Wrong packet!");
|
||||
}
|
||||
else
|
||||
@ -200,7 +129,7 @@ namespace CoopServer
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(string.Format("Player with IP {0} blocked, reason: {1}", message.SenderConnection.RemoteEndPoint.ToString(), e.Message));
|
||||
Logging.Info(string.Format("Player with IP {0} blocked, reason: {1}", message.SenderConnection.RemoteEndPoint.Address.ToString(), e.Message));
|
||||
message.SenderConnection.Deny(e.Message);
|
||||
}
|
||||
}
|
||||
@ -208,11 +137,11 @@ namespace CoopServer
|
||||
case NetIncomingMessageType.StatusChanged:
|
||||
NetConnectionStatus status = (NetConnectionStatus)message.ReadByte();
|
||||
|
||||
player = message.SenderConnection.RemoteUniqueIdentifier;
|
||||
long clientID = message.SenderConnection.RemoteUniqueIdentifier;
|
||||
|
||||
if (status == NetConnectionStatus.Disconnected && Players.ContainsKey(player))
|
||||
if (status == NetConnectionStatus.Disconnected && Clients.Any(x => x.ID == clientID))
|
||||
{
|
||||
SendPlayerDisconnectPacket(new PlayerDisconnectPacket() { Player = player }, message.ReadString());
|
||||
SendPlayerDisconnectPacket(new PlayerDisconnectPacket() { ID = clientID });
|
||||
}
|
||||
break;
|
||||
case NetIncomingMessageType.Data:
|
||||
@ -296,6 +225,18 @@ namespace CoopServer
|
||||
message.SenderConnection.Disconnect(e.Message);
|
||||
}
|
||||
break;
|
||||
case (byte)PacketTypes.ChatMessagePacket:
|
||||
try
|
||||
{
|
||||
packet = new ChatMessagePacket();
|
||||
packet.NetIncomingMessageToPacket(message);
|
||||
SendChatMessage((ChatMessagePacket)packet);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
message.SenderConnection.Disconnect(e.Message);
|
||||
}
|
||||
break;
|
||||
case (byte)PacketTypes.FullSyncNpcPacket:
|
||||
if (MainSettings.NpcsAllowed)
|
||||
{
|
||||
@ -334,27 +275,16 @@ namespace CoopServer
|
||||
message.SenderConnection.Disconnect("Npcs are not allowed!");
|
||||
}
|
||||
break;
|
||||
case (byte)PacketTypes.ChatMessagePacket:
|
||||
try
|
||||
{
|
||||
packet = new ChatMessagePacket();
|
||||
packet.NetIncomingMessageToPacket(message);
|
||||
SendChatMessage((ChatMessagePacket)packet);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
message.SenderConnection.Disconnect(e.Message);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Logging.Error("Unhandled Data / Packet type");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NetIncomingMessageType.ConnectionLatencyUpdated:
|
||||
if (Players.ContainsKey(message.SenderConnection.RemoteUniqueIdentifier))
|
||||
Client client = Clients.FirstOrDefault(x => x.ID == message.SenderConnection.RemoteUniqueIdentifier);
|
||||
if (client != default)
|
||||
{
|
||||
Players[message.SenderConnection.RemoteUniqueIdentifier].Latency = message.ReadFloat();
|
||||
client.Latency = message.ReadFloat();
|
||||
}
|
||||
break;
|
||||
case NetIncomingMessageType.ErrorMessage:
|
||||
@ -381,7 +311,7 @@ namespace CoopServer
|
||||
// Before we approve the connection, we must shake hands
|
||||
private void GetHandshake(NetConnection local, HandshakePacket packet)
|
||||
{
|
||||
Logging.Debug("New handshake from: [" + packet.SocialClubName + " | " + packet.Username + "]");
|
||||
Logging.Debug("New handshake from: [SC: " + packet.SocialClubName + " | Name: " + packet.Username + " | Address: " + local.RemoteEndPoint.Address.ToString() + "]");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(packet.Username))
|
||||
{
|
||||
@ -425,25 +355,29 @@ namespace CoopServer
|
||||
return;
|
||||
}
|
||||
|
||||
if (Players.Any(x => x.Value.SocialClubName == packet.SocialClubName))
|
||||
if (Clients.Any(x => x.Player.SocialClubName == packet.SocialClubName))
|
||||
{
|
||||
local.Deny("The name of the Social Club is already taken!");
|
||||
return;
|
||||
}
|
||||
else if (Players.Any(x => x.Value.Username == packet.Username))
|
||||
else if (Clients.Any(x => x.Player.Username == packet.Username))
|
||||
{
|
||||
local.Deny("Username is already taken!");
|
||||
return;
|
||||
}
|
||||
|
||||
long localPlayerID = local.RemoteUniqueIdentifier;
|
||||
long localID = local.RemoteUniqueIdentifier;
|
||||
|
||||
// Add the player to Players
|
||||
Players.Add(localPlayerID,
|
||||
new EntitiesPlayer()
|
||||
Clients.Add(
|
||||
new Client()
|
||||
{
|
||||
SocialClubName = packet.SocialClubName,
|
||||
Username = packet.Username
|
||||
ID = localID,
|
||||
Player = new()
|
||||
{
|
||||
SocialClubName = packet.SocialClubName,
|
||||
Username = packet.Username
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@ -452,7 +386,7 @@ namespace CoopServer
|
||||
// Create a new handshake packet
|
||||
new HandshakePacket()
|
||||
{
|
||||
ID = localPlayerID,
|
||||
ID = localID,
|
||||
SocialClubName = string.Empty,
|
||||
Username = string.Empty,
|
||||
ModVersion = string.Empty,
|
||||
@ -473,148 +407,182 @@ namespace CoopServer
|
||||
|
||||
if (GameMode != null)
|
||||
{
|
||||
GameMode.API.InvokePlayerConnected(Players[packet.Player]);
|
||||
GameMode.API.InvokePlayerConnected(Clients.Find(x => x.ID == packet.ID));
|
||||
}
|
||||
|
||||
List<NetConnection> playerList = Util.FilterAllLocal(local);
|
||||
if (playerList.Count == 0)
|
||||
List<NetConnection> clients;
|
||||
if ((clients = Util.FilterAllLocal(local)).Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Send all players to local
|
||||
playerList.ForEach(targetPlayer =>
|
||||
clients.ForEach(targetPlayer =>
|
||||
{
|
||||
long targetPlayerID = targetPlayer.RemoteUniqueIdentifier;
|
||||
|
||||
EntitiesPlayer targetEntity = Players[targetPlayerID];
|
||||
Client targetEntity = Clients.First(x => x.ID == targetPlayerID);
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new PlayerConnectPacket()
|
||||
{
|
||||
Player = targetPlayerID,
|
||||
SocialClubName = targetEntity.SocialClubName,
|
||||
Username = targetEntity.Username
|
||||
ID = targetPlayerID,
|
||||
SocialClubName = targetEntity.Player.SocialClubName,
|
||||
Username = targetEntity.Player.Username
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, local, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
});
|
||||
|
||||
// Send local to all players
|
||||
Client localClient = Clients.First(x => x.ID == packet.ID);
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new PlayerConnectPacket()
|
||||
{
|
||||
Player = packet.Player,
|
||||
SocialClubName = Players[packet.Player].SocialClubName,
|
||||
Username = Players[packet.Player].Username
|
||||
ID = packet.ID,
|
||||
SocialClubName = localClient.Player.SocialClubName,
|
||||
Username = localClient.Player.Username
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, playerList, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
// Send all players a message that someone has left the server
|
||||
private static void SendPlayerDisconnectPacket(PlayerDisconnectPacket packet, string reason = "Disconnected")
|
||||
private static void SendPlayerDisconnectPacket(PlayerDisconnectPacket packet)
|
||||
{
|
||||
if (GameMode != null)
|
||||
{
|
||||
GameMode.API.InvokePlayerDisconnected(Players[packet.Player]);
|
||||
GameMode.API.InvokePlayerDisconnected(Clients.Find(x => x.ID == packet.ID));
|
||||
}
|
||||
|
||||
List<NetConnection> playerList = Util.FilterAllLocal(packet.Player);
|
||||
if (playerList.Count != 0)
|
||||
List<NetConnection> clients;
|
||||
if ((clients = Util.FilterAllLocal(packet.ID)).Count == 0)
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, playerList, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
Players.Remove(packet.Player);
|
||||
Clients.Remove(Clients.Find(x => x.ID == packet.ID));
|
||||
}
|
||||
|
||||
private static void FullSyncPlayer(FullSyncPlayerPacket packet)
|
||||
{
|
||||
EntitiesPlayer player = Players[packet.Extra.Player];
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
|
||||
player.Position = packet.Extra.Position;
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
|
||||
List<NetConnection> playerList = Util.FilterAllLocal(packet.Extra.Player);
|
||||
if (playerList.Count == 0)
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.ID).ForEach(x =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
|
||||
PlayerPacket localPacket = packet.Extra;
|
||||
localPacket.Latency = player.Latency;
|
||||
if (Clients.First(y => y.ID == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
|
||||
{
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
new SuperLightSyncPlayerPacket()
|
||||
{
|
||||
Extra = packet.Extra
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
|
||||
packet.Extra = localPacket;
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, playerList, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
}
|
||||
|
||||
private static void FullSyncPlayerVeh(FullSyncPlayerVehPacket packet)
|
||||
{
|
||||
EntitiesPlayer player = Players[packet.Extra.Player];
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
|
||||
player.Position = packet.Extra.Position;
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
|
||||
List<NetConnection> playerList = Util.FilterAllLocal(packet.Extra.Player);
|
||||
if (playerList.Count == 0)
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.ID).ForEach(x =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
|
||||
PlayerPacket localPacket = packet.Extra;
|
||||
localPacket.Latency = player.Latency;
|
||||
if (Clients.First(y => y.ID == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
|
||||
{
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
new SuperLightSyncPlayerPacket()
|
||||
{
|
||||
Extra = packet.Extra
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
|
||||
packet.Extra = localPacket;
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, playerList, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
}
|
||||
|
||||
private static void LightSyncPlayer(LightSyncPlayerPacket packet)
|
||||
{
|
||||
EntitiesPlayer player = Players[packet.Extra.Player];
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
|
||||
player.Position = packet.Extra.Position;
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
|
||||
List<NetConnection> playerList = Util.FilterAllLocal(packet.Extra.Player);
|
||||
if (playerList.Count == 0)
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.ID).ForEach(x =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
|
||||
PlayerPacket localPacket = packet.Extra;
|
||||
localPacket.Latency = player.Latency;
|
||||
if (Clients.First(y => y.ID == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
|
||||
{
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
new SuperLightSyncPlayerPacket()
|
||||
{
|
||||
Extra = packet.Extra
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
|
||||
packet.Extra = localPacket;
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, playerList, NetDeliveryMethod.ReliableSequenced, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
}
|
||||
|
||||
private static void LightSyncPlayerVeh(LightSyncPlayerVehPacket packet)
|
||||
{
|
||||
EntitiesPlayer player = Players[packet.Extra.Player];
|
||||
Client client = Clients.First(x => x.ID == packet.Extra.ID);
|
||||
client.Player.Position = packet.Extra.Position;
|
||||
|
||||
player.Position = packet.Extra.Position;
|
||||
PlayerPacket playerPacket = packet.Extra;
|
||||
playerPacket.Latency = client.Latency;
|
||||
|
||||
List<NetConnection> playerList = Util.FilterAllLocal(packet.Extra.Player);
|
||||
if (playerList.Count == 0)
|
||||
packet.Extra = playerPacket;
|
||||
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.ID).ForEach(x =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
|
||||
PlayerPacket localPacket = packet.Extra;
|
||||
localPacket.Latency = player.Latency;
|
||||
if (Clients.First(y => y.ID == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
|
||||
{
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
new SuperLightSyncPlayerPacket()
|
||||
{
|
||||
Extra = packet.Extra
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
}
|
||||
|
||||
packet.Extra = localPacket;
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, playerList, NetDeliveryMethod.ReliableSequenced, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
});
|
||||
}
|
||||
|
||||
// Send a message to targets or all players
|
||||
@ -632,7 +600,7 @@ namespace CoopServer
|
||||
{
|
||||
CommandContext ctx = new()
|
||||
{
|
||||
Player = Players.First(x => x.Value.Username == packet.Username).Value,
|
||||
Client = Clients.First(x => x.Player.Username == packet.Username),
|
||||
Args = cmdArgs.Skip(1).ToArray()
|
||||
};
|
||||
|
||||
@ -677,24 +645,28 @@ namespace CoopServer
|
||||
#region -- NPC --
|
||||
private static void FullSyncNpc(NetConnection local, FullSyncNpcPacket packet)
|
||||
{
|
||||
List<NetConnection> playerList = Util.GetAllInRange(packet.Position, 300f, local);
|
||||
if (playerList.Count == 0)
|
||||
List<NetConnection> clients;
|
||||
if ((clients = Util.GetAllInRange(packet.Position, 300f, local)).Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, playerList, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
}
|
||||
|
||||
private static void FullSyncNpcVeh(NetConnection local, FullSyncNpcVehPacket packet)
|
||||
{
|
||||
|
||||
List<NetConnection> clients;
|
||||
if ((clients = Util.GetAllInRange(packet.Position, 300f, local)).Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, MainNetServer.Connections, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.UnreliableSequenced, 0);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace CoopServer
|
||||
{
|
||||
#region DELEGATES
|
||||
public delegate void ChatEvent(string username, string message, CancelEventArgs cancel);
|
||||
public delegate void PlayerEvent(Entities.EntitiesPlayer player);
|
||||
public delegate void PlayerEvent(Client client);
|
||||
#endregion
|
||||
|
||||
#region EVENTS
|
||||
@ -31,14 +31,14 @@ namespace CoopServer
|
||||
OnStart?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
internal void InvokePlayerConnected(Entities.EntitiesPlayer player)
|
||||
internal void InvokePlayerConnected(Client client)
|
||||
{
|
||||
OnPlayerConnected?.Invoke(player);
|
||||
OnPlayerConnected?.Invoke(client);
|
||||
}
|
||||
|
||||
internal void InvokePlayerDisconnected(Entities.EntitiesPlayer player)
|
||||
internal void InvokePlayerDisconnected(Client client)
|
||||
{
|
||||
OnPlayerDisconnected?.Invoke(player);
|
||||
OnPlayerDisconnected?.Invoke(client);
|
||||
}
|
||||
|
||||
internal bool InvokeChatMessage(string username, string message)
|
||||
@ -48,23 +48,22 @@ namespace CoopServer
|
||||
return args.Cancel;
|
||||
}
|
||||
|
||||
internal void InvokePlayerPositionUpdate(Entities.EntitiesPlayer player)
|
||||
internal void InvokePlayerPositionUpdate(PlayerData playerData)
|
||||
{
|
||||
OnPlayerPositionUpdate?.Invoke(player);
|
||||
OnPlayerPositionUpdate?.Invoke(Server.Clients.First(x => x.Player.Username == playerData.Username));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region FUNCTIONS
|
||||
public static void SendNativeCallToAll(ulong hash, params object[] args)
|
||||
{
|
||||
List<NetConnection> connections = Server.MainNetServer.Connections;
|
||||
if (connections.Count == 0)
|
||||
if (Server.MainNetServer.ConnectionsCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<NativeArgument> arguments = Util.ParseNativeArguments(args);
|
||||
if (arguments == null)
|
||||
List<NativeArgument> arguments;
|
||||
if ((arguments = Util.ParseNativeArguments(args)) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -80,32 +79,6 @@ namespace CoopServer
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
public static void SendNativeCallToPlayer(string username, ulong hash, params object[] args)
|
||||
{
|
||||
NetConnection userConnection = Util.GetConnectionByUsername(username);
|
||||
if (userConnection == default)
|
||||
{
|
||||
Logging.Warning("[ServerScript->SendNativeCallToPlayer(\"" + username + "\", \"" + hash + "\", params object[] args)]: User not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
List<NativeArgument> arguments = Util.ParseNativeArguments(args);
|
||||
if (arguments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NativeCallPacket packet = new()
|
||||
{
|
||||
Hash = hash,
|
||||
Args = arguments
|
||||
};
|
||||
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
public static List<long> GetAllConnections()
|
||||
{
|
||||
List<long> result = new();
|
||||
@ -115,37 +88,24 @@ namespace CoopServer
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int GetAllPlayersCount()
|
||||
public static int GetAllClientsCount()
|
||||
{
|
||||
return Server.Players.Count;
|
||||
return Server.Clients.Count;
|
||||
}
|
||||
|
||||
public static Dictionary<long, Entities.EntitiesPlayer> GetAllPlayers()
|
||||
public static List<Client> GetAllClients()
|
||||
{
|
||||
return Server.Players;
|
||||
return Server.Clients;
|
||||
}
|
||||
|
||||
public static Entities.EntitiesPlayer GetPlayerByUsername(string username)
|
||||
public static Client GetClientByUsername(string username)
|
||||
{
|
||||
return Server.Players.FirstOrDefault(x => x.Value.Username == username).Value;
|
||||
}
|
||||
|
||||
public static void KickPlayerByUsername(string username, string[] reason)
|
||||
{
|
||||
NetConnection userConnection = Util.GetConnectionByUsername(username);
|
||||
if (userConnection == default)
|
||||
{
|
||||
Logging.Warning("[ServerScript->KickPlayerByUsername(\"" + username + "\", \"" + string.Join(" ", reason) + "\")]: User not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
userConnection.Disconnect(string.Join(" ", reason));
|
||||
return Server.Clients.FirstOrDefault(x => x.Player.Username == username);
|
||||
}
|
||||
|
||||
public static void SendChatMessageToAll(string message, string username = "Server")
|
||||
{
|
||||
List<NetConnection> connections = Server.MainNetServer.Connections;
|
||||
if (connections.Count == 0)
|
||||
if (Server.MainNetServer.ConnectionsCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -161,26 +121,6 @@ namespace CoopServer
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
public static void SendChatMessageToPlayer(string username, string message, string from = "Server")
|
||||
{
|
||||
NetConnection userConnection = Util.GetConnectionByUsername(username);
|
||||
if (userConnection == default)
|
||||
{
|
||||
Logging.Warning("[ServerScript->SendChatMessageToPlayer(\"" + username + "\", \"" + message + "\", \"" + from + "\")]: User not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
ChatMessagePacket packet = new()
|
||||
{
|
||||
Username = from,
|
||||
Message = message
|
||||
};
|
||||
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
|
||||
public static void RegisterCommand(string name, Action<CommandContext> callback)
|
||||
{
|
||||
Server.RegisterCommand(name, callback);
|
||||
@ -217,7 +157,7 @@ namespace CoopServer
|
||||
/// <summary>
|
||||
/// Gets the client which executed the command
|
||||
/// </summary>
|
||||
public Entities.EntitiesPlayer Player { get; internal set; }
|
||||
public Client Client { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chatdata associated with the command
|
||||
|
@ -9,8 +9,6 @@
|
||||
public string GameMode { get; set; } = "";
|
||||
public bool Allowlist { get; set; } = false;
|
||||
public bool NpcsAllowed { get; set; } = true;
|
||||
public string MasterServer { get; set; } = "https://gtacoopr.entenkoeniq.de/servers";
|
||||
public bool AnnounceSelf { get; set; } = true;
|
||||
public bool UPnP { get; set; } = true;
|
||||
public bool DebugMode { get; set; } = false;
|
||||
}
|
||||
|
@ -50,13 +50,13 @@ namespace CoopServer
|
||||
|
||||
public static NetConnection GetConnectionByUsername(string username)
|
||||
{
|
||||
long? userID = Server.Players.FirstOrDefault(x => x.Value.Username == username).Key;
|
||||
if (userID == default || !Server.MainNetServer.Connections.Any(x => x.RemoteUniqueIdentifier == userID))
|
||||
long clientID;
|
||||
if ((clientID = Server.Clients.FirstOrDefault(x => x.Player.Username == username).ID) == default)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Server.MainNetServer.Connections.FirstOrDefault(x => x.RemoteUniqueIdentifier == userID);
|
||||
return Server.MainNetServer.Connections.FirstOrDefault(x => x.RemoteUniqueIdentifier == clientID);
|
||||
}
|
||||
|
||||
// Return a list of all connections but not the local connection
|
||||
@ -72,12 +72,12 @@ namespace CoopServer
|
||||
// Return a list of players within range of ...
|
||||
public static List<NetConnection> GetAllInRange(LVector3 position, float range)
|
||||
{
|
||||
return new(Server.MainNetServer.Connections.FindAll(e => Server.Players[e.RemoteUniqueIdentifier].IsInRangeOf(position, range)));
|
||||
return new(Server.MainNetServer.Connections.FindAll(e => Server.Clients.First(x => x.ID == e.RemoteUniqueIdentifier).Player.IsInRangeOf(position, range)));
|
||||
}
|
||||
// Return a list of players within range of ... but not the local one
|
||||
public static List<NetConnection> GetAllInRange(LVector3 position, float range, NetConnection local)
|
||||
{
|
||||
return new(Server.MainNetServer.Connections.Where(e => e != local && Server.Players[e.RemoteUniqueIdentifier].IsInRangeOf(position, range)));
|
||||
return new(Server.MainNetServer.Connections.Where(e => e != local && Server.Clients.First(x => x.ID == e.RemoteUniqueIdentifier).Player.IsInRangeOf(position, range)));
|
||||
}
|
||||
|
||||
public static T Read<T>(string file) where T : new()
|
||||
|
Reference in New Issue
Block a user