using GTA; using GTA.Math; using GTA.Native; using RageCoop.Client.Menus; using RageCoop.Core; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Drawing; using System.Linq; using System.Windows.Forms; using System.Threading.Tasks; using System.Threading; namespace RageCoop.Client { /// /// Don't use it! /// internal class Main : Script { private bool _gameLoaded = false; internal static readonly string CurrentVersion = "V0_5_0"; internal static int LocalPlayerID = 0; internal static RelationshipGroup SyncedPedsGroup; internal static new Settings Settings = null; internal static Scripting.BaseScript BaseScript = new Scripting.BaseScript(); #if !NON_INTERACTIVE #endif internal static Chat MainChat = null; internal static Stopwatch Counter = new Stopwatch(); internal static Logger Logger = null; internal static ulong Ticked = 0; internal static Vector3 PlayerPosition; internal static Scripting.Resources Resources = null; private static List> QueuedActions = new List>(); public static Worker Worker; /// /// Don't use it! /// public Main() { Worker = new Worker("RageCoop.Client.Main.Worker", Logger); try { Settings = Util.ReadSettings(); } catch { GTA.UI.Notification.Show("Malformed configuration, overwriting with default values..."); Settings=new Settings(); Util.SaveSettings(); } Directory.CreateDirectory(Settings.DataDirectory); Logger=new Logger() { LogPath=$"{Settings.DataDirectory}\\RageCoop.Client.log", UseConsole=false, #if DEBUG LogLevel = 0, #else LogLevel=Settings.LogLevel, #endif }; Resources = new Scripting.Resources(); if (Game.Version < GameVersion.v1_0_1290_1_Steam) { Tick += (object sender, EventArgs e) => { if (Game.IsLoading) { return; } if (!_gameLoaded) { GTA.UI.Notification.Show("~r~Please update your GTA5 to v1.0.1290 or newer!", true); _gameLoaded = true; } }; return; } BaseScript.OnStart(); SyncedPedsGroup=World.AddRelationshipGroup("SYNCPED"); Game.Player.Character.RelationshipGroup.SetRelationshipBetweenGroups(SyncedPedsGroup, Relationship.Neutral, true); #if !NON_INTERACTIVE #endif MainChat = new Chat(); Tick += OnTick; Tick += (s, e) => { Scripting.API.Events.InvokeTick(); }; KeyDown += OnKeyDown; KeyDown+=(s, e) => { Scripting.API.Events.InvokeKeyDown(s, e); }; KeyUp+=(s, e) => { Scripting.API.Events.InvokeKeyUp(s, e); }; Aborted += (object sender, EventArgs e) => CleanUp(); Util.NativeMemory(); Counter.Restart(); } #if DEBUG #endif public static Ped P; public static float FPS; private bool _lastDead; private void OnTick(object sender, EventArgs e) { P= Game.Player.Character; PlayerPosition=P.ReadPosition(); /* var V = P.CurrentVehicle; List found; if (V!=null) { found = Memory.FindOffset(V.Velocity.X, V.MemoryAddress); new LemonUI.Elements.ScaledText(new System.Drawing.PointF(50, 100), V.Velocity.ToString()).Draw(); new LemonUI.Elements.ScaledText(new System.Drawing.PointF(50, 150), V.ReadVelocity().ToString()).Draw(); } else { found = Memory.FindOffset(P.Velocity.X, P.MemoryAddress); new LemonUI.Elements.ScaledText(new System.Drawing.PointF(50, 100), P.Velocity.ToString()).Draw(); new LemonUI.Elements.ScaledText(new System.Drawing.PointF(50, 150), P.ReadVelocity().ToString()).Draw(); } for (int i = 0; i(Hash.GET_HASH_KEY, "FE_MENU_VERSION_SP_PAUSE"), false, 0); return; } if (Game.IsControlPressed(GTA.Control.FrontendPauseAlternate)&&Settings.DisableAlternatePause) { Function.Call(Hash.ACTIVATE_FRONTEND_MENU, Function.Call(Hash.GET_HASH_KEY, "FE_MENU_VERSION_SP_PAUSE"), false, 0); return; } } if (e.KeyCode == Settings.MenuKey) { if (CoopMenu.MenuPool.AreAnyVisible) { CoopMenu.MenuPool.ForEach(x => { if (x.Visible) { CoopMenu.LastMenu=x; x.Visible=false; } }); } else { CoopMenu.LastMenu.Visible = true; } } else if (Game.IsControlJustPressed(GTA.Control.MultiplayerInfo)) { if (Networking.IsOnServer) { ulong currentTimestamp = Util.GetTickCount64(); PlayerList.Pressed = (currentTimestamp - PlayerList.Pressed) < 5000 ? (currentTimestamp - 6000) : currentTimestamp; } } else if (Game.IsControlJustPressed(GTA.Control.MpTextChatAll)) { if (Networking.IsOnServer) { MainChat.Focused = true; } } else if (e.KeyCode==Settings.PassengerKey) { var P = Game.Player.Character; if (!P.IsInVehicle()) { if (P.IsTaskActive(TaskType.CTaskEnterVehicle)) { P.Task.ClearAll(); } else { var V = World.GetClosestVehicle(P.ReadPosition(), 50); if (V!=null) { var seat = P.GetNearestSeat(V); P.Task.EnterVehicle(V, seat); } } } } } public static void CleanUp() { MainChat.Clear(); EntityPool.Cleanup(); PlayerList.Cleanup(); Main.LocalPlayerID=default; } private static void DoQueuedActions() { lock (QueuedActions) { foreach (var action in QueuedActions.ToArray()) { try { if (action()) { QueuedActions.Remove(action); } } catch (Exception ex) { Logger.Error(ex); QueuedActions.Remove(action); } } } } /// /// Queue an action to be executed on next tick, allowing you to call scripting API from another thread. /// /// An action to be executed with a return value indicating whether the action can be removed after execution. internal static void QueueAction(Func a) { lock (QueuedActions) { QueuedActions.Add(a); } } internal static void QueueAction(Action a) { lock (QueuedActions) { QueuedActions.Add(() => { a(); return true; }); } } /// /// Clears all queued actions /// internal static void ClearQueuedActions() { lock (QueuedActions) { QueuedActions.Clear(); } } public static void Delay(Action a, int time) { Task.Run(() => { Thread.Sleep(time); QueueAction(a); }); } } }