diff --git a/Client/Interface.cs b/Client/COOPAPI.cs
similarity index 50%
rename from Client/Interface.cs
rename to Client/COOPAPI.cs
index 8f3914b..eaa30f6 100644
--- a/Client/Interface.cs
+++ b/Client/COOPAPI.cs
@@ -4,17 +4,38 @@ using System.Linq;
namespace CoopClient
{
- public static class Interface
+ ///
+ /// ?
+ ///
+ public static class COOPAPI
{
#region DELEGATES
+ ///
+ /// ?
+ ///
public delegate void ConnectEvent(bool connected, long fromId, string reason = null);
+ ///
+ /// ?
+ ///
public delegate void ChatMessage(string from, string message, CancelEventArgs args);
+ ///
+ /// ?
+ ///
public delegate void ModEvent(long from, string mod, byte customID, byte[] bytes);
#endregion
#region EVENTS
+ ///
+ /// ?
+ ///
public static event ConnectEvent OnConnection;
+ ///
+ /// ?
+ ///
public static event ChatMessage OnChatMessage;
+ ///
+ /// ?
+ ///
public static event ModEvent OnModPacketReceived;
internal static void Connected()
@@ -50,31 +71,55 @@ namespace CoopClient
}
#endregion
- public static void SendChatMessage(string from, string message)
+ ///
+ /// Send a local chat message to this player
+ ///
+ /// Username of the player who sent this message
+ /// The player's message
+ public static void LocalChatMessage(string from, string message)
{
Main.MainChat.AddMessage(from, message);
}
+ ///
+ /// ?
+ ///
public static void Connect(string serverAddress)
{
Main.MainNetworking.DisConnectFromServer(serverAddress);
}
+ ///
+ /// ?
+ ///
public static void Disconnect()
{
Main.MainNetworking.DisConnectFromServer(null);
}
+ ///
+ /// ?
+ ///
public static bool IsOnServer()
{
return Main.MainNetworking.IsOnServer();
}
+ ///
+ /// Get the local ID from this Lidgren network client when connected to a server
+ ///
+ /// long
public static long GetLocalID()
{
return Main.LocalClientID;
}
+ ///
+ /// Get all connected player's as a Dictionary.
+ /// Key = Lidgren-Network client ID
+ /// Value = Character handle or null
+ ///
+ /// Dictionary(long, int)
public static Dictionary GetAllPlayers()
{
Dictionary result = new Dictionary();
@@ -88,11 +133,22 @@ namespace CoopClient
return result;
}
- public static Entities.EntitiesPlayer GetPlayer(long playerId)
+ ///
+ /// Get a player using their Lidgren Network Client ID
+ ///
+ /// Lidgren-Network client ID
+ /// Entities.EntitiesPlayer
+ public static Entities.EntitiesPlayer GetPlayer(long lnID)
{
- return Main.Players.ContainsKey(playerId) ? Main.Players[playerId] : null;
+ lock (Main.Players)
+ {
+ return Main.Players.ContainsKey(lnID) ? Main.Players[lnID] : null;
+ }
}
+ ///
+ /// ?
+ ///
public static bool IsMenuVisible()
{
#if NON_INTERACTIVE
@@ -102,33 +158,76 @@ namespace CoopClient
#endif
}
+ ///
+ /// ?
+ ///
public static bool IsChatFocused()
{
return Main.MainChat.Focused;
}
+ ///
+ /// ?
+ ///
public static bool IsPlayerListVisible()
{
return Util.GetTickCount64() - PlayerList.Pressed < 5000;
}
+ ///
+ /// ?
+ ///
public static string GetCurrentVersion()
{
return Main.CurrentVersion;
}
- // Send bytes to all players
+ ///
+ /// Send any data (bytes) to the server
+ ///
+ /// The name of this modification (script)
+ /// The ID to know what the data is
+ /// Your class, structure or whatever in bytes
+ public static void SendDataToServer(string mod, byte customID, byte[] bytes)
+ {
+ Main.MainNetworking.SendModData(-1, mod, customID, bytes);
+ }
+
+ ///
+ /// Send any data (bytes) to the all player
+ ///
+ /// The name of this modification (script)
+ /// The ID to know what the data is
+ /// Your class, structure or whatever in bytes
public static void SendDataToAll(string mod, byte customID, byte[] bytes)
{
Main.MainNetworking.SendModData(0, mod, customID, bytes);
}
- // Send bytes to target
- public static void SendDataToPlayer(long target, string mod, byte customID, byte[] bytes)
+ ///
+ /// Send any data (bytes) to a player
+ ///
+ /// The Lidgren Network Client ID that receives the data
+ /// The name of this modification (script)
+ /// The ID to know what the data is
+ /// Your class, structure or whatever in bytes
+ public static void SendDataToPlayer(long lnID, string mod, byte customID, byte[] bytes)
{
- Main.MainNetworking.SendModData(target, mod, customID, bytes);
+ Main.MainNetworking.SendModData(lnID, mod, customID, bytes);
}
+ ///
+ /// Get that player's local username that has been set
+ ///
+ /// string
+ public static string GetLocalUsername()
+ {
+ return Main.MainSettings.Username;
+ }
+
+ ///
+ /// ?
+ ///
public static void Configure(string playerName, bool shareNpcsWithPlayers, int streamedNpcs, bool debug = false)
{
Main.MainSettings.Username = playerName;
diff --git a/Client/Chat.cs b/Client/Chat.cs
index 30c422f..4975ca3 100644
--- a/Client/Chat.cs
+++ b/Client/Chat.cs
@@ -8,14 +8,17 @@ using GTA.Native;
namespace CoopClient
{
+ ///
+ /// Don't use it!
+ ///
public class Chat
{
private readonly Scaleform MainScaleForm;
- public string CurrentInput { get; set; }
+ internal string CurrentInput { get; set; }
private bool CurrentFocused { get; set; }
- public bool Focused
+ internal bool Focused
{
get { return CurrentFocused; }
set
@@ -55,23 +58,26 @@ namespace CoopClient
}
}
+ ///
+ /// Don't use it!
+ ///
public Chat()
{
MainScaleForm = new Scaleform("multiplayer_chat");
}
- public void Init()
+ internal void Init()
{
MainScaleForm.CallFunction("SET_FOCUS", 2, 2, "ALL");
MainScaleForm.CallFunction("SET_FOCUS", 1, 2, "ALL");
}
- public void Clear()
+ internal void Clear()
{
MainScaleForm.CallFunction("RESET");
}
- public void Tick()
+ internal void Tick()
{
if ((Util.GetTickCount64() - LastMessageTime) > 15000 && !Focused && !Hidden)
{
@@ -91,14 +97,14 @@ namespace CoopClient
Function.Call(Hash.DISABLE_ALL_CONTROL_ACTIONS, 0);
}
- public void AddMessage(string sender, string msg)
+ internal void AddMessage(string sender, string msg)
{
MainScaleForm.CallFunction("ADD_MESSAGE", sender + ":", msg);
LastMessageTime = Util.GetTickCount64();
Hidden = false;
}
- public void OnKeyDown(Keys key)
+ internal void OnKeyDown(Keys key)
{
if (key == Keys.Escape)
{
@@ -151,12 +157,12 @@ namespace CoopClient
}
[DllImport("user32.dll")]
- public static extern int ToUnicodeEx(uint virtualKeyCode, uint scanCode, byte[] keyboardState,
+ internal static extern int ToUnicodeEx(uint virtualKeyCode, uint scanCode, byte[] keyboardState,
[Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)]
StringBuilder receivingBuffer,
int bufferSize, uint flags, IntPtr kblayout);
- public static string GetCharFromKey(Keys key, bool shift, bool altGr)
+ internal static string GetCharFromKey(Keys key, bool shift, bool altGr)
{
StringBuilder buf = new StringBuilder(256);
byte[] keyboardState = new byte[256];
diff --git a/Client/CoopClient.csproj b/Client/CoopClient.csproj
index 1053733..dcd0cec 100644
--- a/Client/CoopClient.csproj
+++ b/Client/CoopClient.csproj
@@ -24,6 +24,8 @@
4
x64
true
+ Auto
+ bin\Debug\CoopClient.xml
pdbonly
@@ -33,18 +35,26 @@
prompt
4
true
+ Auto
+ bin\Release\CoopClient.xml
-
- ..\Libs\Release\LemonUI.SHVDN3.dll
+
+ False
+ ..\Libs\Release\scripts\LemonUI.SHVDN3.dll
-
- ..\Libs\Release\Lidgren.Network.dll
+
+ False
+ ..\Libs\Release\scripts\Lidgren.Network.dll
-
- ..\packages\protobuf-net.2.4.6\lib\net40\protobuf-net.dll
+
+ False
+ ..\Libs\Release\scripts\Newtonsoft.Json.dll
-
+
+ ..\Libs\Release\scripts\protobuf-net.dll
+
+
False
..\Libs\Release\ScriptHookVDotNet3.dll
@@ -65,13 +75,14 @@
-
+
+
@@ -81,8 +92,5 @@
-
-
-
\ No newline at end of file
diff --git a/Client/Entities/EntitiesNPC.cs b/Client/Entities/EntitiesNPC.cs
index a7a5f14..f230a83 100644
--- a/Client/Entities/EntitiesNPC.cs
+++ b/Client/Entities/EntitiesNPC.cs
@@ -1,5 +1,8 @@
namespace CoopClient.Entities
{
+ ///
+ /// ?
+ ///
public class EntitiesNpc : EntitiesPed
{
//public int LastUpdateReceived { get; set; }
diff --git a/Client/Entities/EntitiesPed.cs b/Client/Entities/EntitiesPed.cs
index da27a74..7ee034e 100644
--- a/Client/Entities/EntitiesPed.cs
+++ b/Client/Entities/EntitiesPed.cs
@@ -9,58 +9,157 @@ using GTA.Math;
using LemonUI.Elements;
-namespace CoopClient
+namespace CoopClient.Entities
{
+ ///
+ /// ?
+ ///
public class EntitiesPed
{
private bool AllDataAvailable = false;
+ ///
+ /// ?
+ ///
public bool LastSyncWasFull { get; set; } = false;
+ ///
+ /// ?
+ ///
public ulong LastUpdateReceived { get; set; }
+ ///
+ /// ?
+ ///
public float Latency { get; set; }
+ ///
+ /// ?
+ ///
public Ped Character { get; set; }
+ ///
+ /// ?
+ ///
public int Health { get; set; }
private int LastModelHash = 0;
+ ///
+ /// ?
+ ///
public int ModelHash { get; set; }
private Dictionary LastProps = new Dictionary();
+ ///
+ /// ?
+ ///
public Dictionary Props { get; set; }
+ ///
+ /// ?
+ ///
public Vector3 Position { get; set; }
#region -- ON FOOT --
+ ///
+ /// ?
+ ///
public Vector3 Rotation { get; set; }
+ ///
+ /// ?
+ ///
public Vector3 Velocity { get; set; }
+ ///
+ /// ?
+ ///
public byte Speed { get; set; }
private bool LastIsJumping = false;
+ ///
+ /// ?
+ ///
public bool IsJumping { get; set; }
+ ///
+ /// ?
+ ///
public bool IsRagdoll { get; set; }
+ ///
+ /// ?
+ ///
public bool IsOnFire { get; set; }
+ ///
+ /// ?
+ ///
public Vector3 AimCoords { get; set; }
+ ///
+ /// ?
+ ///
public bool IsAiming { get; set; }
+ ///
+ /// ?
+ ///
public bool IsShooting { get; set; }
+ ///
+ /// ?
+ ///
public bool IsReloading { get; set; }
+ ///
+ /// ?
+ ///
public int CurrentWeaponHash { get; set; }
#endregion
+ ///
+ /// ?
+ ///
public Blip PedBlip;
#region -- IN VEHICLE --
private ulong VehicleStopTime { get; set; }
+ ///
+ /// ?
+ ///
public bool IsInVehicle { get; set; }
+ ///
+ /// ?
+ ///
public int VehicleModelHash { get; set; }
private int[] LastVehicleColors = new int[] { 0, 0 };
+ ///
+ /// ?
+ ///
public int[] VehicleColors { get; set; }
private Dictionary LastVehicleMods = new Dictionary();
+ ///
+ /// ?
+ ///
public Dictionary VehicleMods { get; set; }
+ ///
+ /// ?
+ ///
public bool VehicleDead { get; set; }
+ ///
+ /// ?
+ ///
public float VehicleEngineHealth { get; set; }
+ ///
+ /// ?
+ ///
public int VehicleSeatIndex { get; set; }
+ ///
+ /// ?
+ ///
public Vehicle MainVehicle { get; set; }
+ ///
+ /// ?
+ ///
public Vector3 VehiclePosition { get; set; }
+ ///
+ /// ?
+ ///
public Quaternion VehicleRotation { get; set; }
+ ///
+ /// ?
+ ///
public Vector3 VehicleVelocity { get; set; }
private float LastVehicleSpeed { get; set; }
private float CurrentVehicleSpeed { get; set; }
+ ///
+ /// ?
+ ///
public float VehicleSpeed
{
set
@@ -69,19 +168,44 @@ namespace CoopClient
CurrentVehicleSpeed = value;
}
}
+ ///
+ /// ?
+ ///
public float VehicleSteeringAngle { get; set; }
+ private int LastVehicleAim;
+ ///
+ /// ?
+ ///
public bool VehIsEngineRunning { get; set; }
+ ///
+ /// ?
+ ///
public float VehRPM { get; set; }
+ ///
+ /// ?
+ ///
public bool VehAreLightsOn { get; set; }
+ ///
+ /// ?
+ ///
public bool VehAreHighBeamsOn { get; set; }
+ ///
+ /// ?
+ ///
public bool VehIsSireneActive { get; set; }
private VehicleDoors[] LastVehDoors;
+ ///
+ /// ?
+ ///
public VehicleDoors[] VehDoors { get; set; }
private int LastVehTires;
+ ///
+ /// ?
+ ///
public int VehTires { get; set; }
#endregion
- public void DisplayLocally(string username)
+ internal void DisplayLocally(string username)
{
/*
* username: string
@@ -297,6 +421,11 @@ namespace CoopClient
}
#region -- VEHICLE SYNC --
+ if (MainVehicle.GetResponsiblePedHandle() != Character.Handle)
+ {
+ return;
+ }
+
if (VehicleColors != null && VehicleColors != LastVehicleColors)
{
Function.Call(Hash.SET_VEHICLE_COLOURS, MainVehicle, VehicleColors[0], VehicleColors[1]);
@@ -322,11 +451,6 @@ namespace CoopClient
}
else
{
- if (MainVehicle.GetResponsiblePedHandle() != Character.Handle)
- {
- return;
- }
-
if (VehicleMods != null && VehicleMods != LastVehicleMods)
{
Function.Call(Hash.SET_VEHICLE_MOD_KIT, MainVehicle, 0);
@@ -437,12 +561,22 @@ namespace CoopClient
LastVehTires = VehTires;
}
+
+ if (AimCoords != default)
+ {
+ int gameTime = Game.GameTime;
+ if (gameTime - LastVehicleAim > 30)
+ {
+ Function.Call(Hash.TASK_VEHICLE_AIM_AT_COORD, Character.Handle, AimCoords.X, AimCoords.Y, AimCoords.Z);
+ LastVehicleAim = gameTime;
+ }
+ }
}
}
-
+
if (VehicleSteeringAngle != MainVehicle.SteeringAngle)
{
- MainVehicle.Handle.CustomSteeringAngle((float)(Math.PI / 180) * VehicleSteeringAngle);
+ MainVehicle.CustomSteeringAngle((float)(Math.PI / 180) * VehicleSteeringAngle);
}
// Good enough for now, but we need to create a better sync
diff --git a/Client/Entities/EntitiesPlayer.cs b/Client/Entities/EntitiesPlayer.cs
index d520161..add3c74 100644
--- a/Client/Entities/EntitiesPlayer.cs
+++ b/Client/Entities/EntitiesPlayer.cs
@@ -1,8 +1,17 @@
namespace CoopClient.Entities
{
+ ///
+ /// ?
+ ///
public class EntitiesPlayer : EntitiesPed
{
+ ///
+ /// ?
+ ///
public string SocialClubName { get; set; }
+ ///
+ /// ?
+ ///
public string Username { get; set; } = "Player";
}
}
diff --git a/Client/Entities/EntitiesThread.cs b/Client/Entities/EntitiesThread.cs
index c6b4f42..387b6ab 100644
--- a/Client/Entities/EntitiesThread.cs
+++ b/Client/Entities/EntitiesThread.cs
@@ -6,12 +6,18 @@ using GTA;
namespace CoopClient.Entities
{
+ ///
+ /// Don't use it!
+ ///
public class EntitiesThread : Script
{
+ ///
+ /// Don't use it!
+ ///
public EntitiesThread()
{
Tick += OnTick;
- Interval = 1000 / 60;
+ Interval = Util.GetGameMs();
}
private void OnTick(object sender, EventArgs e)
diff --git a/Client/Main.cs b/Client/Main.cs
index 4cb419c..81d7d27 100644
--- a/Client/Main.cs
+++ b/Client/Main.cs
@@ -12,31 +12,49 @@ using GTA.Native;
namespace CoopClient
{
+ ///
+ /// Don't use it!
+ ///
public class Main : Script
{
- public static RelationshipGroup RelationshipGroup;
+ internal static RelationshipGroup RelationshipGroup;
private bool GameLoaded = false;
- public static readonly string CurrentVersion = "V0_8_0_1";
+ internal static readonly string CurrentVersion = "V0_9_0";
- public static bool ShareNpcsWithPlayers = false;
- public static bool DisableTraffic = false;
- public static bool NpcsAllowed = false;
+ internal static bool ShareNpcsWithPlayers = false;
+ internal static bool DisableTraffic = false;
+ internal static bool NpcsAllowed = false;
private static bool IsGoingToCar = false;
+ ///
+ /// Don't use it!
+ ///
public static Settings MainSettings = Util.ReadSettings();
+ ///
+ /// Don't use it!
+ ///
public static Networking MainNetworking = new Networking();
#if !NON_INTERACTIVE
+ ///
+ /// Don't use it!
+ ///
public static MenusMain MainMenu = new MenusMain();
#endif
+ ///
+ /// Don't use it!
+ ///
public static Chat MainChat = new Chat();
- public static long LocalClientID = 0;
- public static readonly Dictionary Players = new Dictionary();
- public static readonly Dictionary Npcs = new Dictionary();
+ internal static long LocalClientID = 0;
+ internal static readonly Dictionary Players = new Dictionary();
+ internal static readonly Dictionary Npcs = new Dictionary();
+ ///
+ /// Don't use it!
+ ///
public Main()
{
Function.Call((Hash)0x0888C3502DBBEEF5); // _LOAD_MP_DLC_MAPS
@@ -62,6 +80,8 @@ namespace CoopClient
{
RelationshipGroup = World.AddRelationshipGroup("SYNCPED");
Game.Player.Character.RelationshipGroup = RelationshipGroup;
+
+ GTA.UI.Notification.Show(GTA.UI.NotificationIcon.AllPlayersConf, "GTACOOP:R", "Welcome!", "Press ~g~F9~s~ to open the menu.");
}
#if !NON_INTERACTIVE
@@ -104,7 +124,7 @@ namespace CoopClient
}
#endif
- if ((Util.GetTickCount64() - LastDataSend) < (1000 / 60))
+ if ((Util.GetTickCount64() - LastDataSend) < Util.GetGameMs())
{
return;
}
@@ -182,7 +202,7 @@ namespace CoopClient
}
#endif
- public static void CleanUp()
+ internal static void CleanUp()
{
MainChat.Clear();
@@ -203,24 +223,13 @@ namespace CoopClient
Npc.Value.Character?.Delete();
}
Npcs.Clear();
-
- foreach (Ped entity in World.GetAllPeds().Where(p => p.Handle != Game.Player.Character.Handle))
- {
- entity.Kill();
- entity.Delete();
- }
-
- foreach (Vehicle veh in World.GetAllVehicles().Where(v => v.Handle != Game.Player.Character.CurrentVehicle?.Handle))
- {
- veh.Delete();
- }
}
#if DEBUG
private ulong ArtificialLagCounter;
- public static EntitiesPlayer DebugSyncPed;
- public static ulong LastFullDebugSync = 0;
- public static bool UseDebug = false;
+ internal static EntitiesPlayer DebugSyncPed;
+ internal static ulong LastFullDebugSync = 0;
+ internal static bool UseDebug = false;
private void Debug()
{
@@ -231,12 +240,12 @@ namespace CoopClient
DebugSyncPed = Players[0];
}
- if ((Util.GetTickCount64() - ArtificialLagCounter) < 157)
+ if ((Util.GetTickCount64() - ArtificialLagCounter) < 56)
{
return;
}
- bool fullSync = (Util.GetTickCount64() - LastFullDebugSync) > 1500;
+ bool fullSync = (Util.GetTickCount64() - LastFullDebugSync) > 500;
if (fullSync)
{
@@ -273,6 +282,7 @@ namespace CoopClient
DebugSyncPed.VehicleVelocity = veh.Velocity;
DebugSyncPed.VehicleSpeed = veh.Speed;
DebugSyncPed.VehicleSteeringAngle = veh.SteeringAngle;
+ DebugSyncPed.AimCoords = veh.IsTurretSeat((int)player.SeatIndex) ? Util.GetVehicleAimCoords() : new GTA.Math.Vector3();
DebugSyncPed.VehicleColors = new int[] { primaryColor, secondaryColor };
DebugSyncPed.VehicleMods = veh.Mods.GetVehicleMods();
DebugSyncPed.VehDoors = veh.Doors.GetVehicleDoors();
diff --git a/Client/Menus/MenusMain.cs b/Client/Menus/MenusMain.cs
index f2442a9..61e4527 100644
--- a/Client/Menus/MenusMain.cs
+++ b/Client/Menus/MenusMain.cs
@@ -5,17 +5,27 @@ using LemonUI.Menus;
namespace CoopClient.Menus
{
+ ///
+ /// Don't use it!
+ ///
public class MenusMain
{
- public ObjectPool MenuPool = new ObjectPool();
+ internal ObjectPool MenuPool = new ObjectPool();
- public NativeMenu MainMenu = new NativeMenu("GTACOOP:R", "MAIN")
+ internal NativeMenu MainMenu = new NativeMenu("GTACOOP:R", "MAIN")
{
UseMouse = false,
Alignment = Main.MainSettings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left
};
#region SUB
+ ///
+ /// Don't use it!
+ ///
public Sub.Settings SubSettings = new Sub.Settings();
+ ///
+ /// Don't use it!
+ ///
+ public Sub.Servers ServerList = new Sub.Servers();
#endregion
#region ITEMS
@@ -28,12 +38,17 @@ namespace CoopClient.Menus
Main.CurrentVersion.Replace("_", ".")) { LeftBadge = new LemonUI.Elements.ScaledTexture("commonmenu", "shop_new_star") };
#endregion
+ ///
+ /// Don't use it!
+ ///
public MenusMain()
{
UsernameItem.Activated += UsernameActivated;
ServerIpItem.Activated += ServerIpActivated;
ServerConnectItem.Activated += (sender, item) => { Main.MainNetworking.DisConnectFromServer(Main.MainSettings.LastServerAddress); };
+ MainMenu.AddSubMenu(ServerList.MainMenu);
+
MainMenu.Add(UsernameItem);
MainMenu.Add(ServerIpItem);
MainMenu.Add(ServerConnectItem);
@@ -42,11 +57,12 @@ namespace CoopClient.Menus
MainMenu.Add(AboutItem);
+ MenuPool.Add(ServerList.MainMenu);
MenuPool.Add(MainMenu);
MenuPool.Add(SubSettings.MainMenu);
}
- public void UsernameActivated(object a, System.EventArgs b)
+ internal void UsernameActivated(object a, System.EventArgs b)
{
string newUsername = Game.GetUserInput(WindowTitle.EnterMessage20, UsernameItem.AltTitle, 20);
if (!string.IsNullOrWhiteSpace(newUsername))
@@ -59,7 +75,7 @@ namespace CoopClient.Menus
}
}
- public void ServerIpActivated(object a, System.EventArgs b)
+ internal void ServerIpActivated(object a, System.EventArgs b)
{
string newServerIp = Game.GetUserInput(WindowTitle.EnterMessage60, ServerIpItem.AltTitle, 60);
if (!string.IsNullOrWhiteSpace(newServerIp) && newServerIp.Contains(":"))
@@ -72,29 +88,32 @@ namespace CoopClient.Menus
}
}
- public void InitiateConnectionMenuSetting()
+ internal void InitiateConnectionMenuSetting()
{
MainMenu.Items[0].Enabled = false;
MainMenu.Items[1].Enabled = false;
MainMenu.Items[2].Enabled = false;
+ MainMenu.Items[3].Enabled = false;
}
- public void ConnectedMenuSetting()
+ internal void ConnectedMenuSetting()
{
- MainMenu.Items[2].Enabled = true;
- MainMenu.Items[2].Title = "Disconnect";
+ MainMenu.Items[3].Enabled = true;
+ MainMenu.Items[3].Title = "Disconnect";
SubSettings.MainMenu.Items[1].Enabled = !Main.DisableTraffic && Main.NpcsAllowed;
MainMenu.Visible = false;
+ ServerList.MainMenu.Visible = false;
MenuPool.RefreshAll();
}
- public void DisconnectedMenuSetting()
+ internal void DisconnectedMenuSetting()
{
MainMenu.Items[0].Enabled = true;
MainMenu.Items[1].Enabled = true;
MainMenu.Items[2].Enabled = true;
- MainMenu.Items[2].Title = "Connect";
+ MainMenu.Items[3].Enabled = true;
+ MainMenu.Items[3].Title = "Connect";
SubSettings.MainMenu.Items[1].Enabled = false;
MenuPool.RefreshAll();
diff --git a/Client/Menus/Sub/Servers.cs b/Client/Menus/Sub/Servers.cs
new file mode 100644
index 0000000..1bc4e26
--- /dev/null
+++ b/Client/Menus/Sub/Servers.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Net;
+using System.Collections.Generic;
+
+using Newtonsoft.Json;
+
+using LemonUI.Menus;
+
+namespace CoopClient.Menus.Sub
+{
+ internal class ServerListClass
+ {
+ [JsonProperty("ip")]
+ public string IP { get; set; }
+ [JsonProperty("name")]
+ public string Name { get; set; }
+ [JsonProperty("players")]
+ public int Players { get; set; }
+ [JsonProperty("maxPlayers")]
+ public int MaxPlayers { get; set; }
+ [JsonProperty("allowlist")]
+ public bool AllowList { get; set; }
+ [JsonProperty("mods")]
+ public bool Mods { get; set; }
+ [JsonProperty("npcs")]
+ public bool NPCs { get; set; }
+ [JsonProperty("country")]
+ public string Country { get; set; }
+ }
+
+ ///
+ /// Don't use it!
+ ///
+ public class Servers
+ {
+ internal NativeMenu MainMenu = new NativeMenu("GTACOOP:R", "Servers", "Go to the server list")
+ {
+ UseMouse = false,
+ Alignment = Main.MainSettings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left
+ };
+ internal NativeItem ResultItem = null;
+
+ ///
+ /// Don't use it!
+ ///
+ public Servers()
+ {
+ MainMenu.Opening += (object sender, System.ComponentModel.CancelEventArgs e) =>
+ {
+ MainMenu.Add(ResultItem = new NativeItem("Loading..."));
+ GetAllServer();
+ };
+ MainMenu.Closed += (object sender, EventArgs e) =>
+ {
+ for (int i = 0; i < MainMenu.Items.Count; i++)
+ {
+ MainMenu.Remove(MainMenu.Items[i]);
+ }
+ };
+ }
+ private void GetAllServer()
+ {
+ List serverList = null;
+ try
+ {
+ WebClient client = new WebClient();
+ string data = client.DownloadString(Main.MainSettings.MasterServer);
+ serverList = JsonConvert.DeserializeObject>(data);
+ }
+ catch (Exception ex)
+ {
+ ResultItem.Title = "Download failed!";
+ ResultItem.Description = ex.Message; // You have to use any key to see this message
+ }
+
+ if (serverList == null)
+ {
+ return;
+ }
+
+ if (ResultItem != null)
+ {
+ MainMenu.Remove(MainMenu.Items[0]);
+ ResultItem = null;
+ }
+
+ foreach (ServerListClass server in serverList)
+ {
+ NativeItem tmpItem = null;
+ MainMenu.Add(tmpItem = new NativeItem($"[{server.Country}] {server.Name}", $"~b~{server.IP}~s~~n~Mods = {server.Mods}~n~NPCs = {server.NPCs}") { AltTitle = $"[{server.Players}/{server.MaxPlayers}][{(server.AllowList ? "~r~X~s~" : "~g~O~s~")}]"});
+ tmpItem.Activated += (object sender, EventArgs e) =>
+ {
+ try
+ {
+ MainMenu.Visible = false;
+ Main.MainMenu.MainMenu.Visible = true;
+
+ Main.MainNetworking.DisConnectFromServer(server.IP);
+
+ Main.MainSettings.LastServerAddress = server.IP;
+ Util.SaveSettings();
+ }
+ catch (Exception ex)
+ {
+ GTA.UI.Notification.Show($"~r~{ex.Message}");
+ }
+ };
+ }
+ }
+ }
+}
diff --git a/Client/Menus/Sub/Settings.cs b/Client/Menus/Sub/Settings.cs
index abb8134..4ef99f0 100644
--- a/Client/Menus/Sub/Settings.cs
+++ b/Client/Menus/Sub/Settings.cs
@@ -2,9 +2,12 @@
namespace CoopClient.Menus.Sub
{
+ ///
+ /// Don't use it!
+ ///
public class Settings
{
- public NativeMenu MainMenu = new NativeMenu("GTACOOP:R", "Settings", "Go to the settings")
+ internal NativeMenu MainMenu = new NativeMenu("GTACOOP:R", "Settings", "Go to the settings")
{
UseMouse = false,
Alignment = Main.MainSettings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left
@@ -19,6 +22,9 @@ namespace CoopClient.Menus.Sub
private readonly NativeCheckboxItem ShowNetworkInfo = new NativeCheckboxItem("Show Network Info", Main.MainNetworking.ShowNetworkInfo);
#endif
+ ///
+ /// Don't use it!
+ ///
public Settings()
{
DisableTraffic.CheckboxChanged += DisableTrafficCheckboxChanged;
@@ -40,7 +46,7 @@ namespace CoopClient.Menus.Sub
#endif
}
- public void DisableTrafficCheckboxChanged(object a, System.EventArgs b)
+ internal void DisableTrafficCheckboxChanged(object a, System.EventArgs b)
{
Main.DisableTraffic = DisableTraffic.Checked;
@@ -59,14 +65,14 @@ namespace CoopClient.Menus.Sub
}
}
- public void StreamedNpcsValueChanged(object a, System.EventArgs b)
+ internal void StreamedNpcsValueChanged(object a, System.EventArgs b)
{
Main.MainSettings.StreamedNpc = StreamedNpcsItem.Value;
Util.SaveSettings();
StreamedNpcsItem.Title = string.Format("Streamed Npcs ({0})", Main.MainSettings.StreamedNpc);
}
- public void FlipMenuCheckboxChanged(object a, System.EventArgs b)
+ internal void FlipMenuCheckboxChanged(object a, System.EventArgs b)
{
#if !NON_INTERACTIVE
Main.MainMenu.MainMenu.Alignment = FlipMenuItem.Checked ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left;
@@ -78,7 +84,7 @@ namespace CoopClient.Menus.Sub
}
#if DEBUG
- public void UseDebugCheckboxChanged(object a, System.EventArgs b)
+ internal void UseDebugCheckboxChanged(object a, System.EventArgs b)
{
Main.UseDebug = UseDebugItem.Checked;
@@ -96,7 +102,7 @@ namespace CoopClient.Menus.Sub
}
}
- public void ShowNetworkInfoCheckboxChanged(object a, System.EventArgs b)
+ internal void ShowNetworkInfoCheckboxChanged(object a, System.EventArgs b)
{
Main.MainNetworking.ShowNetworkInfo = ShowNetworkInfo.Checked;
diff --git a/Client/Networking.cs b/Client/Networking.cs
index a59de80..5cb82fc 100644
--- a/Client/Networking.cs
+++ b/Client/Networking.cs
@@ -10,17 +10,20 @@ using GTA.Native;
namespace CoopClient
{
+ ///
+ /// Don't use it!
+ ///
public class Networking
{
- public NetClient Client;
- public float Latency;
+ internal NetClient Client;
+ internal float Latency;
- public bool ShowNetworkInfo = false;
+ internal bool ShowNetworkInfo = false;
- public int BytesReceived = 0;
- public int BytesSend = 0;
+ internal int BytesReceived = 0;
+ internal int BytesSend = 0;
- public void DisConnectFromServer(string address)
+ internal void DisConnectFromServer(string address)
{
if (IsOnServer())
{
@@ -44,9 +47,16 @@ namespace CoopClient
Client.Start();
- string[] ip = address.Split(':');
-
- if(ip.Length != 2)
+ string[] ip = new string[2];
+
+ int idx = address.LastIndexOf(':');
+ if (idx != -1)
+ {
+ ip[0] = address.Substring(0, idx);
+ ip[1] = address.Substring(idx + 1);
+ }
+
+ if (ip.Length != 2)
{
throw new Exception("Malformed URL");
}
@@ -66,12 +76,12 @@ namespace CoopClient
}
}
- public bool IsOnServer()
+ internal bool IsOnServer()
{
return Client?.ConnectionStatus == NetConnectionStatus.Connected;
}
- public void ReceiveMessages()
+ internal void ReceiveMessages()
{
if (Client == null)
{
@@ -114,12 +124,6 @@ namespace CoopClient
Main.LocalClientID = handshakePacket.ID;
Main.NpcsAllowed = handshakePacket.NpcsAllowed;
- Main.CleanUp();
-
- Function.Call(Hash.SET_GARBAGE_TRUCKS, 0);
- Function.Call(Hash.SET_RANDOM_BOATS, 0);
- Function.Call(Hash.SET_RANDOM_TRAINS, 0);
-
Main.MainChat.Init();
// Send player connect packet
@@ -137,7 +141,7 @@ namespace CoopClient
Main.MainMenu.ConnectedMenuSetting();
#endif
- Interface.Connected();
+ COOPAPI.Connected();
GTA.UI.Notification.Show("~g~Connected!");
}
break;
@@ -153,11 +157,12 @@ namespace CoopClient
}
Main.CleanUp();
+
#if !NON_INTERACTIVE
Main.MainMenu.DisconnectedMenuSetting();
#endif
- Interface.Disconnected(reason);
+ COOPAPI.Disconnected(reason);
GTA.UI.Notification.Show("~r~Disconnected: " + reason);
break;
}
@@ -219,7 +224,7 @@ namespace CoopClient
packet.NetIncomingMessageToPacket(message);
ChatMessagePacket chatMessagePacket = (ChatMessagePacket)packet;
- if (!Interface.ChatMessageReceived(chatMessagePacket.Username, chatMessagePacket.Message))
+ if (!COOPAPI.ChatMessageReceived(chatMessagePacket.Username, chatMessagePacket.Message))
{
Main.MainChat.AddMessage(chatMessagePacket.Username, chatMessagePacket.Message);
}
@@ -233,7 +238,7 @@ namespace CoopClient
packet = new ModPacket();
packet.NetIncomingMessageToPacket(message);
ModPacket modPacket = (ModPacket)packet;
- Interface.ModPacketReceived(modPacket.ID, modPacket.Mod, modPacket.CustomPacketID, modPacket.Bytes);
+ COOPAPI.ModPacketReceived(modPacket.ID, modPacket.Mod, modPacket.CustomPacketID, modPacket.Bytes);
break;
}
break;
@@ -244,6 +249,9 @@ namespace CoopClient
case NetIncomingMessageType.ErrorMessage:
case NetIncomingMessageType.WarningMessage:
case NetIncomingMessageType.VerboseDebugMessage:
+#if DEBUG
+ // TODO?
+#endif
break;
default:
break;
@@ -265,7 +273,7 @@ namespace CoopClient
};
Main.Players.Add(packet.ID, player);
- Interface.Connected(packet.ID);
+ COOPAPI.Connected(packet.ID);
}
private void PlayerDisconnect(PlayerDisconnectPacket packet)
@@ -281,7 +289,7 @@ namespace CoopClient
player.PedBlip?.Delete();
- Interface.Disconnected(packet.ID);
+ COOPAPI.Disconnected(packet.ID);
Main.Players.Remove(packet.ID);
}
}
@@ -334,6 +342,7 @@ namespace CoopClient
player.VehicleVelocity = packet.VehVelocity.ToVector();
player.VehicleSpeed = packet.VehSpeed;
player.VehicleSteeringAngle = packet.VehSteeringAngle;
+ player.AimCoords = packet.VehAimCoords.ToVector();
player.VehicleColors = packet.VehColors;
player.VehicleMods = packet.VehMods;
player.VehDoors = packet.VehDoors;
@@ -590,7 +599,7 @@ namespace CoopClient
#region -- SEND --
private ulong LastPlayerFullSync = 0;
- public void SendPlayerData()
+ internal void SendPlayerData()
{
Ped player = Game.Player.Character;
@@ -660,6 +669,7 @@ namespace CoopClient
VehVelocity = vehVelocity,
VehSpeed = vehSpeed,
VehSteeringAngle = vehSteeringAngle,
+ VehAimCoords = veh.IsTurretSeat((int)player.SeatIndex) ? Util.GetVehicleAimCoords().ToLVector() : new LVector3(),
VehColors = new int[] { primaryColor, secondaryColor },
VehMods = vehMods,
VehDoors = vehDoors,
@@ -762,7 +772,7 @@ namespace CoopClient
#endif
}
- public void SendNpcData(Ped npc)
+ internal void SendNpcData(Ped npc)
{
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
@@ -859,7 +869,7 @@ namespace CoopClient
#endif
}
- public void SendChatMessage(string message)
+ internal void SendChatMessage(string message)
{
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
new ChatMessagePacket()
@@ -878,7 +888,7 @@ namespace CoopClient
#endif
}
- public void SendModData(long target, string mod, byte customID, byte[] bytes)
+ internal void SendModData(long target, string mod, byte customID, byte[] bytes)
{
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
new ModPacket()
diff --git a/Client/Packets.cs b/Client/Packets.cs
index 1588dd5..ce45898 100644
--- a/Client/Packets.cs
+++ b/Client/Packets.cs
@@ -1,10 +1,10 @@
using System;
using System.IO;
using System.Collections.Generic;
-using System.Runtime.Serialization.Formatters.Binary;
using Lidgren.Network;
using ProtoBuf;
+using Newtonsoft.Json;
using GTA.Math;
@@ -156,10 +156,16 @@ namespace CoopClient
IsDead = 1 << 5
}
+ ///
+ /// ?
+ ///
[ProtoContract]
public struct VehicleDoors
{
#region CLIENT-ONLY
+ ///
+ /// ?
+ ///
public VehicleDoors(float angleRatio = 0f, bool broken = false, bool open = false, bool fullyOpen = false)
{
AngleRatio = angleRatio;
@@ -169,27 +175,39 @@ namespace CoopClient
}
#endregion
+ ///
+ /// ?
+ ///
[ProtoMember(1)]
public float AngleRatio { get; set; }
+ ///
+ /// ?
+ ///
[ProtoMember(2)]
public bool Broken { get; set; }
+ ///
+ /// ?
+ ///
[ProtoMember(3)]
public bool Open { get; set; }
+ ///
+ /// ?
+ ///
[ProtoMember(4)]
public bool FullyOpen { get; set; }
}
#endregion
- public interface IPacket
+ interface IPacket
{
void PacketToNetOutGoingMessage(NetOutgoingMessage message);
void NetIncomingMessageToPacket(NetIncomingMessage message);
}
- public abstract class Packet : IPacket
+ abstract class Packet : IPacket
{
public abstract void PacketToNetOutGoingMessage(NetOutgoingMessage message);
public abstract void NetIncomingMessageToPacket(NetIncomingMessage message);
@@ -454,18 +472,21 @@ namespace CoopClient
public float VehSteeringAngle { get; set; }
[ProtoMember(13)]
- public int[] VehColors { get; set; }
+ public LVector3 VehAimCoords { get; set; }
[ProtoMember(14)]
- public Dictionary VehMods { get; set; }
+ public int[] VehColors { get; set; }
[ProtoMember(15)]
- public VehicleDoors[] VehDoors { get; set; }
+ public Dictionary VehMods { get; set; }
[ProtoMember(16)]
- public int VehTires { get; set; }
+ public VehicleDoors[] VehDoors { get; set; }
[ProtoMember(17)]
+ public int VehTires { get; set; }
+
+ [ProtoMember(18)]
public byte? Flag { get; set; } = 0;
public override void PacketToNetOutGoingMessage(NetOutgoingMessage message)
@@ -496,6 +517,7 @@ namespace CoopClient
VehVelocity = data.VehVelocity;
VehSpeed = data.VehSpeed;
VehSteeringAngle = data.VehSteeringAngle;
+ VehAimCoords = data.VehAimCoords;
VehColors = data.VehColors;
VehMods = data.VehMods;
VehDoors = data.VehDoors;
@@ -910,8 +932,14 @@ namespace CoopClient
}
#endregion
+ ///
+ /// ?
+ ///
public static class CoopSerializer
{
+ ///
+ /// ?
+ ///
public static byte[] CSerialize(this object obj)
{
if (obj == null)
@@ -919,14 +947,13 @@ namespace CoopClient
return null;
}
- BinaryFormatter bf = new BinaryFormatter();
- using (MemoryStream ms = new MemoryStream())
- {
- bf.Serialize(ms, obj);
- return ms.ToArray();
- }
+ string jsonString = JsonConvert.SerializeObject(obj);
+ return System.Text.Encoding.UTF8.GetBytes(jsonString);
}
+ ///
+ /// ?
+ ///
public static T CDeserialize(this byte[] bytes) where T : class
{
if (bytes == null)
@@ -934,14 +961,8 @@ namespace CoopClient
return null;
}
- using (MemoryStream memStream = new MemoryStream())
- {
- BinaryFormatter binForm = new BinaryFormatter();
- memStream.Write(bytes, 0, bytes.Length);
- memStream.Seek(0, SeekOrigin.Begin);
- T obj = (T)binForm.Deserialize(memStream);
- return obj;
- }
+ var jsonString = System.Text.Encoding.UTF8.GetString(bytes);
+ return JsonConvert.DeserializeObject(jsonString);
}
internal static T Deserialize(this byte[] data) where T : new()
diff --git a/Client/PlayerList.cs b/Client/PlayerList.cs
index eed62d5..7b02f1c 100644
--- a/Client/PlayerList.cs
+++ b/Client/PlayerList.cs
@@ -8,12 +8,18 @@ using GTA.Native;
namespace CoopClient
{
+ ///
+ /// Don't use it!
+ ///
public class PlayerList : Script
{
private readonly Scaleform MainScaleform = new Scaleform("mp_mm_card_freemode");
private ulong LastUpdate = Util.GetTickCount64();
- public static ulong Pressed { get; set; }
+ internal static ulong Pressed { get; set; }
+ ///
+ /// Don't use it!
+ ///
public PlayerList()
{
Init();
diff --git a/Client/Settings.cs b/Client/Settings.cs
index 6ea215f..d56cb91 100644
--- a/Client/Settings.cs
+++ b/Client/Settings.cs
@@ -1,10 +1,29 @@
namespace CoopClient
{
+ ///
+ /// Don't use it!
+ ///
public class Settings
{
+ ///
+ /// Don't use it!
+ ///
public string Username { get; set; } = "Player";
+ ///
+ /// Don't use it!
+ ///
public string LastServerAddress { get; set; } = "127.0.0.1:4499";
+ ///
+ /// Don't use it!
+ ///
+ public string MasterServer { get; set; } = "http://gtacoopr.000webhostapp.com/servers.php";
+ ///
+ /// Don't use it!
+ ///
public bool FlipMenu { get; set; } = false;
+ ///
+ /// Don't use it!
+ ///
public int StreamedNpc { get; set; } = 10;
}
}
diff --git a/Client/Util.cs b/Client/Util.cs
index 0718042..fc3ecbb 100644
--- a/Client/Util.cs
+++ b/Client/Util.cs
@@ -2,9 +2,7 @@
using System.IO;
using System.Xml.Serialization;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Runtime.InteropServices;
-using static System.Runtime.InteropServices.Marshal;
using GTA;
using GTA.Native;
@@ -17,60 +15,29 @@ namespace CoopClient
#region -- POINTER --
private static int SteeringAngleOffset { get; set; }
- delegate ulong GetHandleAddressFuncDelegate(int handle);
- static GetHandleAddressFuncDelegate GetEntityAddressFunc;
-
- static unsafe byte* FindPattern(string pattern, string mask)
- {
- ProcessModule module = Process.GetCurrentProcess().MainModule;
-
- ulong address = (ulong)module.BaseAddress.ToInt64();
- ulong endAddress = address + (ulong)module.ModuleMemorySize;
-
- for (; address < endAddress; address++)
- {
- for (int i = 0; i < pattern.Length; i++)
- {
- if (mask[i] != '?' && ((byte*)address)[i] != pattern[i])
- {
- break;
- }
- else if (i + 1 == pattern.Length)
- {
- return (byte*)address;
- }
- }
- }
-
- return null;
- }
-
public static unsafe void NativeMemory()
{
- byte* address;
+ IntPtr address;
- address = FindPattern("\xE8\x00\x00\x00\x00\x48\x8B\xD8\x48\x85\xC0\x74\x2E\x48\x83\x3D", "x????xxxxxxxxxxx");
- GetEntityAddressFunc = GetDelegateForFunctionPointer(new IntPtr(*(int*)(address + 1) + address + 5));
-
- address = FindPattern("\x74\x0A\xF3\x0F\x11\xB3\x1C\x09\x00\x00\xEB\x25", "xxxxxx????xx");
- if (address != null)
+ address = Game.FindPattern("\x74\x0A\xF3\x0F\x11\xB3\x1C\x09\x00\x00\xEB\x25", "xxxxxx????xx");
+ if (address != IntPtr.Zero)
{
SteeringAngleOffset = *(int*)(address + 6) + 8;
}
- address = FindPattern("\x32\xc0\xf3\x0f\x11\x09", "xxxxxx"); // Weapon / Radio slowdown
- if (address != null)
+ address = Game.FindPattern("\x32\xc0\xf3\x0f\x11\x09", "xxxxxx"); // Weapon / Radio slowdown
+ if (address != IntPtr.Zero)
{
for (int i = 0; i < 6; i++)
{
- *(byte*)((IntPtr)address + i).ToPointer() = 0x90;
+ *(byte*)(address + i).ToPointer() = 0x90;
}
}
}
- public static unsafe void CustomSteeringAngle(this int handle, float value)
+ public static unsafe void CustomSteeringAngle(this Vehicle veh, float value)
{
- IntPtr address = new IntPtr((long)GetEntityAddressFunc(handle));
+ IntPtr address = new IntPtr((long)veh.MemoryAddress);
if (address == IntPtr.Zero || SteeringAngleOffset == 0)
{
return;
@@ -80,6 +47,11 @@ namespace CoopClient
}
#endregion
+ public static T GetGameMs() where T : IConvertible
+ {
+ return (T)Convert.ChangeType(1f / (Game.FPS > 60f ? 60f : Game.FPS) * 1000f, typeof(T));
+ }
+
public static Model ModelRequest(this int hash)
{
Model model = new Model(hash);
@@ -167,6 +139,15 @@ namespace CoopClient
return aimOrShoot ? (isNpc ? GetLastWeaponImpact(ped) : RaycastEverything(new Vector2(0, 0))) : new Vector3();
}
+ ///
+ /// Only works for players NOT NPCs
+ ///
+ /// Vector3
+ public static Vector3 GetVehicleAimCoords()
+ {
+ return RaycastEverything(new Vector2(0, 0));
+ }
+
public static byte? GetVehicleFlags(this Vehicle veh, bool fullSync)
{
byte? flags = 0;
@@ -365,6 +346,38 @@ namespace CoopClient
return coord.GetResult();
}
+ public static bool IsTurretSeat(this Vehicle veh, int seat)
+ {
+ if (!Function.Call(Hash.DOES_VEHICLE_HAVE_WEAPONS, veh.Handle))
+ {
+ return false;
+ }
+
+ switch (seat)
+ {
+ case -1:
+ return (VehicleHash)veh.Model.Hash == VehicleHash.Rhino
+ || (VehicleHash)veh.Model.Hash == VehicleHash.Khanjari
+ || (VehicleHash)veh.Model.Hash == VehicleHash.FireTruck;
+ case 1:
+ return (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie
+ || (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie2
+ || (VehicleHash)veh.Model.Hash == VehicleHash.Technical
+ || (VehicleHash)veh.Model.Hash == VehicleHash.Technical2
+ || (VehicleHash)veh.Model.Hash == VehicleHash.Technical3
+ || (VehicleHash)veh.Model.Hash == VehicleHash.HalfTrack; // Not sure
+ case 2:
+ return (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie
+ || (VehicleHash)veh.Model.Hash == VehicleHash.Valkyrie2;
+ case 3:
+ return (VehicleHash)veh.Model.Hash == VehicleHash.Limo2;
+ case 7:
+ return (VehicleHash)veh.Model.Hash == VehicleHash.Insurgent;
+ }
+
+ return false;
+ }
+
public static double DegToRad(double deg)
{
return deg * Math.PI / 180.0;
diff --git a/Client/WorldThread.cs b/Client/WorldThread.cs
index 8a5096a..feddba1 100644
--- a/Client/WorldThread.cs
+++ b/Client/WorldThread.cs
@@ -6,14 +6,20 @@ using GTA.Native;
namespace CoopClient
{
+ ///
+ /// Don't use it!
+ ///
public class WorldThread : Script
{
private static bool LastDisableTraffic = false;
+ ///
+ /// Don't use it!
+ ///
public WorldThread()
{
Tick += OnTick;
- Interval = 1000 / 60;
+ Interval = Util.GetGameMs();
Aborted += (sender, e) =>
{
if (LastDisableTraffic)
@@ -23,7 +29,7 @@ namespace CoopClient
};
}
- public static void OnTick(object sender, EventArgs e)
+ internal static void OnTick(object sender, EventArgs e)
{
if (Game.IsLoading)
{
diff --git a/Client/packages.config b/Client/packages.config
deleted file mode 100644
index bd81797..0000000
--- a/Client/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/FirstGameMod/FirstGameMode.sln b/FirstGameMod/FirstGameMode.sln
deleted file mode 100644
index ce30111..0000000
--- a/FirstGameMod/FirstGameMode.sln
+++ /dev/null
@@ -1,25 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.31605.320
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FirstGameMode", "FirstGameMode\FirstGameMode.csproj", "{212B1A61-0C03-4B0E-A53C-2CC6B667E0DA}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {212B1A61-0C03-4B0E-A53C-2CC6B667E0DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {212B1A61-0C03-4B0E-A53C-2CC6B667E0DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {212B1A61-0C03-4B0E-A53C-2CC6B667E0DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {212B1A61-0C03-4B0E-A53C-2CC6B667E0DA}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {3C329584-BE48-469B-85D8-FD24F47BD033}
- EndGlobalSection
-EndGlobal
diff --git a/FirstGameMod/FirstGameMode/Commands.cs b/FirstGameMod/FirstGameMode/Commands.cs
deleted file mode 100644
index 03fd7fc..0000000
--- a/FirstGameMod/FirstGameMode/Commands.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using CoopServer;
-using System.Collections.Generic;
-
-namespace FirstGameMode
-{
- class Commands
- {
- [Command("set")]
- public static void TimeCommand(CommandContext ctx)
- {
- if (ctx.Args.Length < 1)
- {
- ctx.Client.SendChatMessage("Please use \"/set