├── .gitattributes ├── .gitignore ├── AdminTools ├── AdminTools.csproj ├── MainFilterscript.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ └── Settings.settings └── app.config ├── Client ├── Chat.cs ├── ChatData.cs ├── DebugWindow.cs ├── GTACoOp.csproj ├── Main.cs ├── NativeData.cs ├── PedThread.cs ├── PlayerSettings.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── SyncPed.cs ├── Util.cs ├── VehicleData.cs └── packages.config ├── GTACoOp.sln ├── LICENSE.md ├── README.md ├── Race ├── Gamemode.cs ├── Properties │ └── AssemblyInfo.cs ├── Race.cs ├── Race.csproj └── VehicleHashes.cs ├── Server ├── App.config ├── ChatData.cs ├── GTAServer.csproj ├── GameServer.cs ├── NativeData.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── ServerScript.cs ├── ServerSettings.cs ├── VehicleData.cs └── packages.config ├── gtamasterserver ├── .gitignore ├── Procfile ├── app.py ├── json_test.py ├── ping_test.py └── requirements.txt └── libs ├── Lidgren.Network.dll ├── NativeUI.dll ├── Newtonsoft.Json.dll ├── ScriptHookVDotNet.dll └── protobuf-net.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | *.csproj 214 | -------------------------------------------------------------------------------- /AdminTools/AdminTools.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {158CCEB2-E6EC-457B-BA61-E448BD6B0F40} 8 | Library 9 | Properties 10 | AdminTools 11 | AdminTools 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ..\libs\Lidgren.Network.dll 43 | 44 | 45 | False 46 | ..\libs\Newtonsoft.Json.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | True 62 | True 63 | Settings.settings 64 | 65 | 66 | 67 | 68 | {559ee224-bf7b-49d8-9cee-11e6ba71fe4e} 69 | GTAServer 70 | 71 | 72 | 73 | 74 | 75 | SettingsSingleFileGenerator 76 | Settings.Designer.cs 77 | 78 | 79 | 80 | 87 | -------------------------------------------------------------------------------- /AdminTools/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestGamemode")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TestGamemode")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("158cceb2-e6ec-457b-ba61-e448bd6b0f40")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /AdminTools/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace AdminTools.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 29 | public bool KickOnDefaultName { 30 | get { 31 | return ((bool)(this["KickOnDefaultName"])); 32 | } 33 | set { 34 | this["KickOnDefaultName"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 41 | public bool KickOnNameDifference { 42 | get { 43 | return ((bool)(this["KickOnNameDifference"])); 44 | } 45 | set { 46 | this["KickOnNameDifference"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 53 | public bool SocialClubOnly { 54 | get { 55 | return ((bool)(this["SocialClubOnly"])); 56 | } 57 | set { 58 | this["SocialClubOnly"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("Welcome to this GTA 5 Co-op Server! Max Ping: 250")] 65 | public string MOTD { 66 | get { 67 | return ((string)(this["MOTD"])); 68 | } 69 | set { 70 | this["MOTD"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | [global::System.Configuration.DefaultSettingValueAttribute("250")] 77 | public int MaxPing { 78 | get { 79 | return ((int)(this["MaxPing"])); 80 | } 81 | set { 82 | this["MaxPing"] = value; 83 | } 84 | } 85 | 86 | [global::System.Configuration.UserScopedSettingAttribute()] 87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 88 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 89 | public bool AntiClones { 90 | get { 91 | return ((bool)(this["AntiClones"])); 92 | } 93 | set { 94 | this["AntiClones"] = value; 95 | } 96 | } 97 | 98 | [global::System.Configuration.UserScopedSettingAttribute()] 99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 100 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 101 | public bool KickOnOutdatedScript { 102 | get { 103 | return ((bool)(this["KickOnOutdatedScript"])); 104 | } 105 | set { 106 | this["KickOnOutdatedScript"] = value; 107 | } 108 | } 109 | 110 | [global::System.Configuration.UserScopedSettingAttribute()] 111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 112 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 113 | public bool KickOnOutdatedGame { 114 | get { 115 | return ((bool)(this["KickOnOutdatedGame"])); 116 | } 117 | set { 118 | this["KickOnOutdatedGame"] = value; 119 | } 120 | } 121 | 122 | [global::System.Configuration.UserScopedSettingAttribute()] 123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 124 | [global::System.Configuration.DefaultSettingValueAttribute("VERSION_0_9")] 125 | public string ScriptVersion { 126 | get { 127 | return ((string)(this["ScriptVersion"])); 128 | } 129 | set { 130 | this["ScriptVersion"] = value; 131 | } 132 | } 133 | 134 | [global::System.Configuration.UserScopedSettingAttribute()] 135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 136 | [global::System.Configuration.DefaultSettingValueAttribute("26")] 137 | public string GameVersion { 138 | get { 139 | return ((string)(this["GameVersion"])); 140 | } 141 | set { 142 | this["GameVersion"] = value; 143 | } 144 | } 145 | 146 | [global::System.Configuration.UserScopedSettingAttribute()] 147 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 148 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 149 | public bool ColoredNicknames { 150 | get { 151 | return ((bool)(this["ColoredNicknames"])); 152 | } 153 | set { 154 | this["ColoredNicknames"] = value; 155 | } 156 | } 157 | 158 | [global::System.Configuration.UserScopedSettingAttribute()] 159 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 160 | [global::System.Configuration.DefaultSettingValueAttribute("[~h~EU~n~/~b~G~r~E~y~R~n~] Blu\'s World (LSPD:FR|Roleplay|Fun)")] 161 | public string ServerName { 162 | get { 163 | return ((string)(this["ServerName"])); 164 | } 165 | set { 166 | this["ServerName"] = value; 167 | } 168 | } 169 | 170 | [global::System.Configuration.UserScopedSettingAttribute()] 171 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 172 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 173 | public bool OnlyAsciiNickName { 174 | get { 175 | return ((bool)(this["OnlyAsciiNickName"])); 176 | } 177 | set { 178 | this["OnlyAsciiNickName"] = value; 179 | } 180 | } 181 | 182 | [global::System.Configuration.UserScopedSettingAttribute()] 183 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 184 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 185 | public bool OnlyAsciiUserName { 186 | get { 187 | return ((bool)(this["OnlyAsciiUserName"])); 188 | } 189 | set { 190 | this["OnlyAsciiUserName"] = value; 191 | } 192 | } 193 | 194 | [global::System.Configuration.UserScopedSettingAttribute()] 195 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 196 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 197 | public bool LimitNickNames { 198 | get { 199 | return ((bool)(this["LimitNickNames"])); 200 | } 201 | set { 202 | this["LimitNickNames"] = value; 203 | } 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /AdminTools/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | True 7 | 8 | 9 | False 10 | 11 | 12 | True 13 | 14 | 15 | Welcome to this GTA 5 Co-op Server! Max Ping: 250 16 | 17 | 18 | 250 19 | 20 | 21 | False 22 | 23 | 24 | True 25 | 26 | 27 | False 28 | 29 | 30 | VERSION_0_9 31 | 32 | 33 | 26 34 | 35 | 36 | True 37 | 38 | 39 | [~h~EU~n~/~b~G~r~E~y~R~n~] Blu's World (LSPD:FR|Roleplay|Fun) 40 | 41 | 42 | True 43 | 44 | 45 | False 46 | 47 | 48 | True 49 | 50 | 51 | -------------------------------------------------------------------------------- /AdminTools/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | True 12 | 13 | 14 | False 15 | 16 | 17 | True 18 | 19 | 20 | Welcome to this GTA 5 Co-op Server! Max Ping: 250 21 | 22 | 23 | 250 24 | 25 | 26 | False 27 | 28 | 29 | True 30 | 31 | 32 | False 33 | 34 | 35 | VERSION_0_9 36 | 37 | 38 | 26 39 | 40 | 41 | True 42 | 43 | 44 | [~h~EU~n~/~b~G~r~E~y~R~n~] Blu's World (LSPD:FR|Roleplay|Fun) 45 | 46 | 47 | True 48 | 49 | 50 | False 51 | 52 | 53 | True 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Client/Chat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Windows.Forms; 8 | using GTA; 9 | using GTA.Native; 10 | using NativeUI; 11 | using Control = GTA.Control; 12 | using Font = GTA.Font; 13 | 14 | namespace GTACoOp 15 | { 16 | public class Chat 17 | { 18 | public event EventHandler OnComplete; 19 | 20 | public Chat() 21 | { 22 | CurrentInput = ""; 23 | _mainScaleform = new Scaleform(0); 24 | _mainScaleform.Load("multiplayer_chat"); 25 | } 26 | 27 | public bool HasInitialized; 28 | 29 | public void Init() 30 | { 31 | _mainScaleform.CallFunction("SET_FOCUS", 2, 2, "ALL"); 32 | _mainScaleform.CallFunction("SET_FOCUS", 1, 2, "ALL"); 33 | HasInitialized = true; 34 | } 35 | 36 | public bool IsFocused 37 | { 38 | get { return _isFocused; } 39 | set 40 | { 41 | if (value && !_isFocused) 42 | { 43 | _mainScaleform.CallFunction("SET_FOCUS", 2, 2, "ALL"); 44 | } 45 | else if (!value && _isFocused) 46 | { 47 | _mainScaleform.CallFunction("SET_FOCUS", 1, 2, "ALL"); 48 | } 49 | 50 | _isFocused = value; 51 | 52 | } 53 | } 54 | 55 | private Scaleform _mainScaleform; 56 | 57 | public string CurrentInput; 58 | 59 | private int _switch = 1; 60 | private Keys _lastKey; 61 | private bool _isFocused; 62 | 63 | public void Tick() 64 | { 65 | if (!Main.IsOnServer()) return; 66 | 67 | _mainScaleform.Render2D(); 68 | 69 | 70 | if (!IsFocused) return; 71 | Function.Call(Hash.DISABLE_ALL_CONTROL_ACTIONS, 0); 72 | } 73 | 74 | public void AddMessage(string sender, string msg) 75 | { 76 | if (string.IsNullOrEmpty(sender)) 77 | _mainScaleform.CallFunction("ADD_MESSAGE", "", SanitizeString(msg)); 78 | else 79 | _mainScaleform.CallFunction("ADD_MESSAGE", SanitizeString(sender) + ":", SanitizeString(msg)); 80 | } 81 | 82 | public string SanitizeString(string input) 83 | { 84 | input = Regex.Replace(input, "~.~", "", RegexOptions.IgnoreCase); 85 | return input; 86 | } 87 | 88 | public void OnKeyDown(Keys key) 89 | { 90 | if (key == Keys.PageUp && Main.IsOnServer()) 91 | _mainScaleform.CallFunction("PAGE_UP"); 92 | 93 | else if (key == Keys.PageDown && Main.IsOnServer()) 94 | _mainScaleform.CallFunction("PAGE_DOWN"); 95 | 96 | if (!IsFocused) return; 97 | 98 | if ((key == Keys.ShiftKey && _lastKey == Keys.Menu) || (key == Keys.Menu && _lastKey == Keys.ShiftKey)) 99 | ActivateKeyboardLayout(1, 0); 100 | 101 | _lastKey = key; 102 | 103 | if (key == Keys.Escape) 104 | { 105 | IsFocused = false; 106 | CurrentInput = ""; 107 | } 108 | 109 | var keyChar = GetCharFromKey(key, Game.IsKeyPressed(Keys.ShiftKey), false); 110 | 111 | if (keyChar.Length == 0) return; 112 | 113 | if (keyChar[0] == (char)8) 114 | { 115 | _mainScaleform.CallFunction("SET_FOCUS", 1, 2, "ALL"); 116 | _mainScaleform.CallFunction("SET_FOCUS", 2, 2, "ALL"); 117 | 118 | if (CurrentInput.Length > 0) 119 | { 120 | CurrentInput = CurrentInput.Substring(0, CurrentInput.Length - 1); 121 | _mainScaleform.CallFunction("ADD_TEXT", CurrentInput); 122 | } 123 | return; 124 | } 125 | if (keyChar[0] == (char)13) 126 | { 127 | _mainScaleform.CallFunction("ADD_TEXT", "ENTER"); 128 | if (OnComplete != null) OnComplete.Invoke(this, EventArgs.Empty); 129 | CurrentInput = ""; 130 | return; 131 | } 132 | var str = keyChar; 133 | 134 | CurrentInput += str; 135 | _mainScaleform.CallFunction("ADD_TEXT", str); 136 | } 137 | 138 | 139 | [DllImport("user32.dll")] 140 | public static extern int ToUnicodeEx(uint virtualKeyCode, uint scanCode, 141 | byte[] keyboardState, 142 | [Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)] 143 | StringBuilder receivingBuffer, 144 | int bufferSize, uint flags, IntPtr kblayout); 145 | 146 | [DllImport("user32.dll")] 147 | public static extern int ActivateKeyboardLayout(int hkl, uint flags); 148 | 149 | public static string GetCharFromKey(Keys key, bool shift, bool altGr) 150 | { 151 | var buf = new StringBuilder(256); 152 | var keyboardState = new byte[256]; 153 | if (shift) 154 | keyboardState[(int)Keys.ShiftKey] = 0xff; 155 | if (altGr) 156 | { 157 | keyboardState[(int)Keys.ControlKey] = 0xff; 158 | keyboardState[(int)Keys.Menu] = 0xff; 159 | } 160 | 161 | ToUnicodeEx((uint)key, 0, keyboardState, buf, 256, 0, InputLanguage.CurrentInputLanguage.Handle); 162 | return buf.ToString(); 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /Client/ChatData.cs: -------------------------------------------------------------------------------- 1 | using ProtoBuf; 2 | 3 | namespace GTACoOp 4 | { 5 | [ProtoContract] 6 | public class ChatData 7 | { 8 | [ProtoMember(1)] 9 | public long Id { get; set; } 10 | [ProtoMember(2)] 11 | public string Sender { get; set; } 12 | [ProtoMember(3)] 13 | public string Message { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Client/DebugWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Linq; 4 | using GTA; 5 | using NativeUI; 6 | 7 | namespace GTACoOp 8 | { 9 | public class DebugWindow 10 | { 11 | public bool Visible { get; set; } 12 | public int PlayerIndex { get; set; } 13 | 14 | public void Draw() 15 | { 16 | if (!Visible) return; 17 | 18 | if (Game.IsControlJustPressed(0, Control.FrontendLeft)) 19 | { 20 | PlayerIndex--; 21 | } 22 | 23 | else if (Game.IsControlJustPressed(0, Control.FrontendRight)) 24 | { 25 | PlayerIndex++; 26 | } 27 | 28 | if (PlayerIndex >= Main.Opponents.Count || PlayerIndex < 0) 29 | { 30 | // wrong index 31 | return; 32 | } 33 | 34 | var player = Main.Opponents.ElementAt(PlayerIndex); 35 | string output = "=======PLAYER #" + PlayerIndex + " INFO=======\n"; 36 | output += "Name: " + player.Value.Name + "\n"; 37 | output += "UID: " + player.Key + "\n"; 38 | output += "IsInVehicle: " + player.Value.IsInVehicle + "\n"; 39 | output += "Position: " + player.Value.Position + "\n"; 40 | output += "VehiclePosition: " + player.Value.VehiclePosition + "\n"; 41 | output += "VehModel: " + player.Value.VehicleHash + "\n"; 42 | output += "Last Updated: " + player.Value.LastUpdateReceived + "\n"; 43 | output += "Latency: " + player.Value.Latency + "\n"; 44 | output += "Character Pos: " + player.Value.Character?.Position + "\n"; 45 | output += "CharacterIsInVeh: " + player.Value.Character?.IsInVehicle() + "\n"; 46 | output += "Net Speed: " + player.Value.Speed + "\n"; 47 | output += "Char Speed: " + player.Value.Character?.CurrentVehicle?.Speed + "\n"; 48 | 49 | new UIResText(output, new Point(500, 10), 0.5f) {Outline = true}.Draw(); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /Client/GTACoOp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1BC495C9-DC44-478A-9E16-3FC482A8B850} 8 | Library 9 | Properties 10 | GTACoOp 11 | GTACoOp 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | AnyCPU 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | x64 34 | 35 | 36 | 37 | 38 | 39 | 40 | ..\libs\Lidgren.Network.dll 41 | 42 | 43 | ..\libs\NativeUI.dll 44 | 45 | 46 | False 47 | ..\libs\Newtonsoft.Json.dll 48 | 49 | 50 | ..\libs\protobuf-net.dll 51 | 52 | 53 | ..\libs\ScriptHookVDotNet.dll 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 99 | -------------------------------------------------------------------------------- /Client/NativeData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using ProtoBuf; 4 | 5 | namespace GTACoOp 6 | { 7 | [ProtoContract] 8 | public class NativeResponse 9 | { 10 | [ProtoMember(1)] 11 | public NativeArgument Response { get; set; } 12 | 13 | [ProtoMember(2)] 14 | public string Id { get; set; } 15 | } 16 | 17 | [ProtoContract] 18 | public class NativeTickCall 19 | { 20 | [ProtoMember(1)] 21 | public NativeData Native { get; set; } 22 | 23 | [ProtoMember(2)] 24 | public string Identifier { get; set; } 25 | } 26 | 27 | [ProtoContract] 28 | public class NativeData 29 | { 30 | [ProtoMember(1)] 31 | public ulong Hash { get; set; } 32 | 33 | [ProtoMember(2)] 34 | public List Arguments { get; set; } 35 | 36 | [ProtoMember(3)] 37 | public NativeArgument ReturnType { get; set; } 38 | 39 | [ProtoMember(4)] 40 | public string Id { get; set; } 41 | } 42 | 43 | [ProtoContract] 44 | [ProtoInclude(2, typeof(IntArgument))] 45 | [ProtoInclude(3, typeof(UIntArgument))] 46 | [ProtoInclude(4, typeof(StringArgument))] 47 | [ProtoInclude(5, typeof(FloatArgument))] 48 | [ProtoInclude(6, typeof(BooleanArgument))] 49 | [ProtoInclude(7, typeof(LocalPlayerArgument))] 50 | [ProtoInclude(8, typeof(Vector3Argument))] 51 | [ProtoInclude(9, typeof(LocalGamePlayerArgument))] 52 | public class NativeArgument 53 | { 54 | [ProtoMember(1)] 55 | public string Id { get; set; } 56 | } 57 | 58 | [ProtoContract] 59 | public class LocalPlayerArgument : NativeArgument 60 | { 61 | } 62 | 63 | [ProtoContract] 64 | public class LocalGamePlayerArgument : NativeArgument 65 | { 66 | } 67 | 68 | [ProtoContract] 69 | public class OpponentPedHandleArgument : NativeArgument 70 | { 71 | public OpponentPedHandleArgument(long opponentHandle) 72 | { 73 | Data = opponentHandle; 74 | } 75 | 76 | [ProtoMember(1)] 77 | public long Data { get; set; } 78 | } 79 | 80 | [ProtoContract] 81 | public class IntArgument : NativeArgument 82 | { 83 | [ProtoMember(1)] 84 | public int Data { get; set; } 85 | } 86 | 87 | [ProtoContract] 88 | public class UIntArgument : NativeArgument 89 | { 90 | [ProtoMember(1)] 91 | public uint Data { get; set; } 92 | } 93 | 94 | [ProtoContract] 95 | public class StringArgument : NativeArgument 96 | { 97 | [ProtoMember(1)] 98 | public string Data { get; set; } 99 | } 100 | 101 | [ProtoContract] 102 | public class FloatArgument : NativeArgument 103 | { 104 | [ProtoMember(1)] 105 | public float Data { get; set; } 106 | } 107 | 108 | [ProtoContract] 109 | public class BooleanArgument : NativeArgument 110 | { 111 | [ProtoMember(1)] 112 | public bool Data { get; set; } 113 | } 114 | 115 | 116 | [ProtoContract] 117 | public class Vector3Argument : NativeArgument 118 | { 119 | [ProtoMember(1)] 120 | public float X { get; set; } 121 | [ProtoMember(2)] 122 | public float Y { get; set; } 123 | [ProtoMember(3)] 124 | public float Z { get; set; } 125 | } 126 | } -------------------------------------------------------------------------------- /Client/PedThread.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using GTA; 5 | 6 | namespace GTACoOp 7 | { 8 | public class PedThread : Script 9 | { 10 | public PedThread() 11 | { 12 | Tick += OnTick; 13 | } 14 | 15 | public void OnTick(object sender, EventArgs e) 16 | { 17 | if (!Main.IsOnServer()) return; 18 | 19 | const int npcThreshold = 5000; // 5 second timeout 20 | const int playerThreshold = 60000; // 60 second timeout 21 | 22 | Dictionary localOpps = null; 23 | lock (Main.Opponents) localOpps = new Dictionary(Main.Opponents); 24 | for (int i = localOpps.Count - 1; i >= 0; i--) 25 | { 26 | if (DateTime.Now.Subtract(localOpps.ElementAt(i).Value.LastUpdateReceived).TotalMilliseconds > playerThreshold) 27 | { 28 | var key = localOpps.ElementAt(i).Key; 29 | localOpps[key].Clear(); 30 | localOpps.Remove(key); 31 | } 32 | } 33 | 34 | Dictionary localNpcs = null; 35 | lock (Main.Npcs) localNpcs = new Dictionary(Main.Npcs); 36 | for (int i = localNpcs.Count - 1; i >= 0; i--) 37 | { 38 | if (DateTime.Now.Subtract(localNpcs.ElementAt(i).Value.LastUpdateReceived).TotalMilliseconds > npcThreshold) 39 | { 40 | var key = localNpcs.ElementAt(i).Key; 41 | localNpcs[key].Clear(); 42 | localNpcs.Remove(key); 43 | } 44 | } 45 | 46 | lock (Main.Opponents) foreach (KeyValuePair opp in new Dictionary(Main.Opponents)) if (!localOpps.ContainsKey(opp.Key)) Main.Opponents.Remove(opp.Key); 47 | 48 | lock (Main.Npcs) foreach (KeyValuePair npc in new Dictionary(Main.Npcs)) if (!localNpcs.ContainsKey(npc.Key)) Main.Npcs.Remove(npc.Key); 49 | 50 | for (int i = 0; i < localOpps.Count; i++) localOpps.ElementAt(i).Value.DisplayLocally(); 51 | 52 | for (int i = 0; i < localNpcs.Count; i++) localNpcs.ElementAt(i).Value.DisplayLocally(); 53 | 54 | if (Main.SendNpcs) 55 | { 56 | var list = new List(localNpcs.Where(pair => pair.Value.Character != null).Select(pair => pair.Value.Character.Handle)); 57 | list.AddRange(localOpps.Where(pair => pair.Value.Character != null).Select(pair => pair.Value.Character.Handle)); 58 | list.Add(Game.Player.Character.Handle); 59 | 60 | foreach (Ped ped in World.GetAllPeds() 61 | .OrderBy(p => (p.Position - Game.Player.Character.Position).Length()) 62 | .Take(Main.PlayerSettings.MaxStreamedNpcs == 0 ? 10 : Main.PlayerSettings.MaxStreamedNpcs)) 63 | { 64 | if (!list.Contains(ped.Handle)) 65 | { 66 | Main.SendPedData(ped); 67 | } 68 | } 69 | } 70 | 71 | Main.SendPlayerData(); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Client/PlayerSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace GTACoOp 4 | { 5 | public class PlayerSettings 6 | { 7 | public string DisplayName { get; set; } 8 | public int MaxStreamedNpcs { get; set; } 9 | public string MasterServerAddress { get; set; } 10 | public Keys ActivationKey { get; set; } 11 | 12 | public PlayerSettings() 13 | { 14 | DisplayName = string.IsNullOrWhiteSpace(GTA.Game.Player.Name) ? "Player" : GTA.Game.Player.Name; 15 | MaxStreamedNpcs = 10; 16 | MasterServerAddress = "http://46.101.1.92/"; 17 | ActivationKey = Keys.F9; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Client/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Threading; 5 | using System.Xml.Serialization; 6 | using GTA; 7 | using GTA.Native; 8 | using Lidgren.Network; 9 | using ProtoBuf; 10 | 11 | namespace GTACoOp 12 | { 13 | public static class Program 14 | { 15 | public static string Location { get { return AppDomain.CurrentDomain.BaseDirectory; } } 16 | 17 | public static void Main(string[] args) 18 | { 19 | Console.WriteLine("Starting..."); 20 | 21 | SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); 22 | 23 | var _config = new NetPeerConfiguration("GTAVOnlineRaces"); 24 | _config.Port = new Random().Next(1000, 9999); 25 | 26 | var _client = new NetClient(_config); 27 | _client.Start(); 28 | 29 | var msg = _client.CreateMessage(); 30 | msg.Write("Player"); 31 | _client.Connect("127.0.0.1", 4499, msg); 32 | _client.RegisterReceivedCallback(ProcessMessages, SynchronizationContext.Current); 33 | 34 | while (true) 35 | { 36 | } 37 | } 38 | 39 | public static void ProcessMessages(object sender) 40 | { 41 | Console.WriteLine("Received message."); 42 | 43 | var peer = (NetPeer)sender; 44 | var msg = peer.ReadMessage(); 45 | 46 | var type = (PacketType)msg.ReadInt32(); 47 | 48 | 49 | Console.WriteLine("Data is " + type); 50 | 51 | switch (type) 52 | { 53 | case PacketType.ChatData: 54 | { 55 | var len = msg.ReadInt32(); 56 | var data = DeserializeBinary(msg.ReadBytes(len)) as ChatData; 57 | if (data != null) Console.WriteLine("Chat: " + data.Message); 58 | } 59 | break; 60 | case PacketType.VehiclePositionData: 61 | { 62 | var len = msg.ReadInt32(); 63 | var data = DeserializeBinary(msg.ReadBytes(len)) as VehicleData; 64 | Console.WriteLine("Updated Vehicle Data"); 65 | } 66 | break; 67 | } 68 | } 69 | 70 | public static object DeserializeBinary(byte[] data) 71 | { 72 | object output; 73 | using (var stream = new MemoryStream(data)) 74 | { 75 | try 76 | { 77 | output = Serializer.Deserialize(stream); 78 | } 79 | catch (ProtoException e) 80 | { 81 | Console.WriteLine("ERROR: " + e.Message); 82 | return null; 83 | } 84 | } 85 | return output; 86 | } 87 | 88 | public static byte[] SerializeBinary(object data) 89 | { 90 | using (var stream = new MemoryStream()) 91 | { 92 | stream.SetLength(0); 93 | Serializer.Serialize(stream, data); 94 | return stream.ToArray(); 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("GTACoOp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("GTACoOp")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1bc495c9-dc44-478a-9e16-3fc482a8b850")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Client/SyncPed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | using GTA; 6 | using GTA.Math; 7 | using GTA.Native; 8 | using NativeUI; 9 | using Font = GTA.Font; 10 | 11 | namespace GTACoOp 12 | { 13 | public enum SynchronizationMode 14 | { 15 | Tasks, 16 | Teleport, 17 | } 18 | 19 | public class SyncPed 20 | { 21 | public SynchronizationMode SyncMode; 22 | public long Host; 23 | public Ped Character; 24 | public Vector3 Position; 25 | public Quaternion Rotation; 26 | public bool IsInVehicle; 27 | public bool IsJumping; 28 | public int ModelHash; 29 | public int CurrentWeapon; 30 | public bool IsShooting; 31 | public bool IsAiming; 32 | public Vector3 AimCoords; 33 | public float Latency; 34 | public bool IsHornPressed; 35 | public Vehicle MainVehicle { get; set; } 36 | 37 | public int VehicleSeat; 38 | public int PedHealth; 39 | 40 | public int VehicleHealth; 41 | public int VehicleHash; 42 | public Quaternion VehicleRotation; 43 | public int VehiclePrimaryColor; 44 | public int VehicleSecondaryColor; 45 | public string Name; 46 | public bool Siren; 47 | 48 | public float Speed 49 | { 50 | get { return _speed; } 51 | set 52 | { 53 | _lastSpeed = _speed; 54 | _speed = value; 55 | } 56 | } 57 | 58 | public bool IsParachuteOpen; 59 | 60 | public double AverageLatency 61 | { 62 | get { return _latencyAverager.Average(); } 63 | } 64 | 65 | public DateTime LastUpdateReceived 66 | { 67 | get { return _lastUpdateReceived; } 68 | set 69 | { 70 | _secondToLastUpdateReceived = _lastUpdateReceived; 71 | _lastUpdateReceived = value; 72 | 73 | if (_secondToLastUpdateReceived != null && _lastUpdateReceived != null) 74 | { 75 | _latencyAverager.Enqueue(_lastUpdateReceived.Subtract(_secondToLastUpdateReceived).TotalMilliseconds); 76 | if (_latencyAverager.Count >= 10) 77 | _latencyAverager.Dequeue(); 78 | } 79 | } 80 | } 81 | 82 | public Dictionary VehicleMods 83 | { 84 | get { return _vehicleMods; } 85 | set 86 | { 87 | if (value == null) return; 88 | _vehicleMods = value; 89 | } 90 | } 91 | 92 | public Dictionary PedProps 93 | { 94 | get { return _pedProps; } 95 | set 96 | { 97 | if (value == null) return; 98 | _pedProps = value; 99 | } 100 | } 101 | 102 | private Vector3 _lastVehiclePos; 103 | public Vector3 VehiclePosition 104 | { 105 | get { return _vehiclePosition; } 106 | set 107 | { 108 | _lastVehiclePos = _vehiclePosition; 109 | _vehiclePosition = value; 110 | } 111 | } 112 | 113 | private bool _lastVehicle; 114 | private uint _switch; 115 | private bool _lastAiming; 116 | private float _lastSpeed; 117 | private DateTime _secondToLastUpdateReceived; 118 | private bool _lastShooting; 119 | private bool _lastJumping; 120 | private bool _blip; 121 | private bool _justEnteredVeh; 122 | private DateTime _lastHornPress = DateTime.Now; 123 | private int _relGroup; 124 | private DateTime _enterVehicleStarted; 125 | private Vector3 _vehiclePosition; 126 | private Dictionary _vehicleMods; 127 | private Dictionary _pedProps; 128 | 129 | private Queue _latencyAverager; 130 | 131 | private int _playerSeat; 132 | private bool _isStreamedIn; 133 | private Blip _mainBlip; 134 | private bool _lastHorn; 135 | private Prop _parachuteProp; 136 | 137 | public SyncPed(int hash, Vector3 pos, Quaternion rot, bool blip = true) 138 | { 139 | Position = pos; 140 | Rotation = rot; 141 | ModelHash = hash; 142 | _blip = blip; 143 | 144 | _latencyAverager = new Queue(); 145 | 146 | _relGroup = World.AddRelationshipGroup("SYNCPED"); 147 | World.SetRelationshipBetweenGroups(Relationship.Neutral, _relGroup, Game.Player.Character.RelationshipGroup); 148 | World.SetRelationshipBetweenGroups(Relationship.Neutral, Game.Player.Character.RelationshipGroup, _relGroup); 149 | } 150 | 151 | public void SetBlipNameFromTextFile(Blip blip, string text) 152 | { 153 | Function.Call(Hash._0xF9113A30DE5C6670, "STRING"); 154 | Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, text); 155 | Function.Call(Hash._0xBC38B49BCB83BC9B, blip); 156 | } 157 | 158 | private int _modSwitch = 0; 159 | private int _clothSwitch = 0; 160 | private DateTime _lastUpdateReceived; 161 | private float _speed; 162 | 163 | public void DisplayLocally() 164 | { 165 | const float hRange = 200f; 166 | var gPos = IsInVehicle ? VehiclePosition : Position; 167 | var inRange = Game.Player.Character.IsInRangeOf(gPos, hRange); 168 | 169 | if (inRange && !_isStreamedIn) 170 | { 171 | _isStreamedIn = true; 172 | if (_mainBlip != null) 173 | { 174 | _mainBlip.Remove(); 175 | _mainBlip = null; 176 | } 177 | } 178 | else if(!inRange && _isStreamedIn) 179 | { 180 | Clear(); 181 | _isStreamedIn = false; 182 | } 183 | 184 | if (!inRange) 185 | { 186 | if (_mainBlip == null && _blip) 187 | { 188 | _mainBlip = World.CreateBlip(gPos); 189 | _mainBlip.Color = BlipColor.White; 190 | _mainBlip.Scale = 0.8f; 191 | SetBlipNameFromTextFile(_mainBlip, Name == null ? "" : Name); 192 | } 193 | if(_blip && _mainBlip != null) 194 | _mainBlip.Position = gPos; 195 | return; 196 | } 197 | 198 | 199 | if (Character == null || !Character.Exists() || !Character.IsInRangeOf(gPos, hRange) || Character.Model.Hash != ModelHash || (Character.IsDead && PedHealth > 0)) 200 | { 201 | if (Character != null) Character.Delete(); 202 | 203 | Character = World.CreatePed(new Model(ModelHash), gPos, Rotation.Z); 204 | if (Character == null) return; 205 | 206 | Character.BlockPermanentEvents = true; 207 | Character.IsInvincible = true; 208 | Character.CanRagdoll = false; 209 | Character.RelationshipGroup = _relGroup; 210 | if (_blip) 211 | { 212 | Character.AddBlip(); 213 | if (Character.CurrentBlip == null) return; 214 | Character.CurrentBlip.Color = BlipColor.White; 215 | Character.CurrentBlip.Scale = 0.8f; 216 | SetBlipNameFromTextFile(Character.CurrentBlip, Name); 217 | } 218 | return; 219 | } 220 | 221 | if (!Character.IsOccluded && Character.IsInRangeOf(Game.Player.Character.Position, 20f)) 222 | { 223 | var oldPos = UI.WorldToScreen(Character.Position + new Vector3(0, 0, 1.5f)); 224 | if (oldPos.X != 0 && oldPos.Y != 0) 225 | { 226 | var res = UIMenu.GetScreenResolutionMantainRatio(); 227 | var pos = new Point((int)((oldPos.X / (float)UI.WIDTH) * res.Width), 228 | (int)((oldPos.Y / (float)UI.HEIGHT) * res.Height)); 229 | 230 | 231 | new UIResText(Name == null ? "" : Name, pos, 0.3f, Color.WhiteSmoke, Font.ChaletLondon, UIResText.Alignment.Centered) 232 | { 233 | Outline = true, 234 | }.Draw(); 235 | } 236 | } 237 | 238 | if ((!_lastVehicle && IsInVehicle && VehicleHash != 0) || (_lastVehicle && IsInVehicle && (MainVehicle == null || !Character.IsInVehicle(MainVehicle) || MainVehicle.Model.Hash != VehicleHash || VehicleSeat != Util.GetPedSeat(Character)))) 239 | { 240 | if (MainVehicle != null && Util.IsVehicleEmpty(MainVehicle)) 241 | MainVehicle.Delete(); 242 | 243 | var vehs = World.GetAllVehicles().OrderBy(v => 244 | { 245 | if (v == null) return float.MaxValue; 246 | return (v.Position - Character.Position).Length(); 247 | }).ToList(); 248 | 249 | 250 | if (vehs.Any() && vehs[0].Model.Hash == VehicleHash && vehs[0].IsInRangeOf(gPos, 3f)) 251 | { 252 | MainVehicle = vehs[0]; 253 | if (Game.Player.Character.IsInVehicle(MainVehicle) && 254 | VehicleSeat == Util.GetPedSeat(Game.Player.Character)) 255 | { 256 | Game.Player.Character.Task.WarpOutOfVehicle(MainVehicle); 257 | UI.Notify("~r~Car jacked!"); 258 | } 259 | } 260 | else 261 | { 262 | MainVehicle = World.CreateVehicle(new Model(VehicleHash), gPos, 0); 263 | } 264 | 265 | if (MainVehicle != null) 266 | { 267 | MainVehicle.PrimaryColor = (VehicleColor)VehiclePrimaryColor; 268 | MainVehicle.SecondaryColor = (VehicleColor)VehicleSecondaryColor; 269 | MainVehicle.Quaternion = VehicleRotation; 270 | MainVehicle.IsInvincible = true; 271 | Character.Task.WarpIntoVehicle(MainVehicle, (VehicleSeat)VehicleSeat); 272 | 273 | /*if (_playerSeat != -2 && !Game.Player.Character.IsInVehicle(_mainVehicle)) 274 | { // TODO: Fix me. 275 | Game.Player.Character.Task.WarpIntoVehicle(_mainVehicle, (VehicleSeat)_playerSeat); 276 | }*/ 277 | } 278 | 279 | _lastVehicle = true; 280 | _justEnteredVeh = true; 281 | _enterVehicleStarted = DateTime.Now; 282 | return; 283 | } 284 | 285 | if (_lastVehicle && _justEnteredVeh && IsInVehicle && !Character.IsInVehicle(MainVehicle) && DateTime.Now.Subtract(_enterVehicleStarted).TotalSeconds <= 4) 286 | { 287 | return; 288 | } 289 | _justEnteredVeh = false; 290 | 291 | if (_lastVehicle && !IsInVehicle && MainVehicle != null) 292 | { 293 | if (Character != null) Character.Task.LeaveVehicle(MainVehicle, true); 294 | } 295 | 296 | Character.Health = PedHealth; 297 | 298 | _switch++; 299 | if (IsInVehicle) 300 | { 301 | if (VehicleSeat == (int) GTA.VehicleSeat.Driver || 302 | MainVehicle.GetPedOnSeat(GTA.VehicleSeat.Driver) == null) 303 | { 304 | MainVehicle.Health = VehicleHealth; 305 | if (MainVehicle.Health <= 0) 306 | { 307 | MainVehicle.IsInvincible = false; 308 | //_mainVehicle.Explode(); 309 | } 310 | else 311 | { 312 | MainVehicle.IsInvincible = true; 313 | if (MainVehicle.IsDead) 314 | MainVehicle.Repair(); 315 | } 316 | 317 | MainVehicle.PrimaryColor = (VehicleColor) VehiclePrimaryColor; 318 | MainVehicle.SecondaryColor = (VehicleColor) VehicleSecondaryColor; 319 | 320 | if (VehicleMods != null && _modSwitch%50 == 0 && 321 | Game.Player.Character.IsInRangeOf(VehiclePosition, 30f)) 322 | { 323 | var id = _modSwitch/50; 324 | 325 | if (VehicleMods.ContainsKey(id) && VehicleMods[id] != MainVehicle.GetMod((VehicleMod) id)) 326 | { 327 | Function.Call(Hash.SET_VEHICLE_MOD_KIT, MainVehicle.Handle, 0); 328 | MainVehicle.SetMod((VehicleMod) id, VehicleMods[id], false); 329 | Function.Call(Hash.RELEASE_PRELOAD_MODS, id); 330 | } 331 | } 332 | _modSwitch++; 333 | 334 | if (_modSwitch >= 2500) 335 | _modSwitch = 0; 336 | 337 | if (IsHornPressed && !_lastHorn) 338 | { 339 | _lastHorn = true; 340 | MainVehicle.SoundHorn(99999); 341 | } 342 | 343 | if (!IsHornPressed && _lastHorn) 344 | { 345 | _lastHorn = false; 346 | MainVehicle.SoundHorn(1); 347 | } 348 | 349 | if (MainVehicle.SirenActive && !Siren) 350 | MainVehicle.SirenActive = Siren; 351 | else if (!MainVehicle.SirenActive && Siren) 352 | MainVehicle.SirenActive = Siren; 353 | 354 | var dir = VehiclePosition - _lastVehiclePos; 355 | 356 | dir.Normalize(); 357 | 358 | var range = Math.Max(20f, Speed*Math.Ceiling(DateTime.Now.Subtract(LastUpdateReceived).TotalSeconds)); 359 | 360 | if (MainVehicle.IsInRangeOf(VehiclePosition, (float) range)) 361 | { 362 | var timeElapsed = (float) DateTime.Now.Subtract(LastUpdateReceived).TotalSeconds; 363 | var acceleration = Speed - _lastSpeed; 364 | MainVehicle.Position = _lastVehiclePos + dir*(Speed*timeElapsed) + 365 | dir*(0.5f*acceleration*(float) Math.Pow(timeElapsed, 2)); 366 | } 367 | else 368 | { 369 | MainVehicle.Position = VehiclePosition; 370 | _lastVehiclePos = VehiclePosition - (dir*0.5f); 371 | } 372 | #if DEBUG 373 | if (MainVehicle.Heading < 270) 374 | MainVehicle.Quaternion = Util.LerpQuaternion(MainVehicle.Quaternion, VehicleRotation, 0.1f); 375 | else if (MainVehicle.Heading >= 270) 376 | MainVehicle.Quaternion = Util.LerpQuaternion(VehicleRotation, MainVehicle.Quaternion, 0.1f); 377 | #else 378 | MainVehicle.Quaternion = VehicleRotation; 379 | #endif 380 | } 381 | } 382 | else 383 | { 384 | if (PedProps != null && _clothSwitch%50 == 0 && Game.Player.Character.IsInRangeOf(Position, 30f)) 385 | { 386 | var id = _clothSwitch/50; 387 | 388 | if (PedProps.ContainsKey(id) && 389 | PedProps[id] != Function.Call(Hash.GET_PED_DRAWABLE_VARIATION, Character.Handle, id)) 390 | { 391 | Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Character.Handle, id, PedProps[id], 0, 0); 392 | } 393 | } 394 | 395 | _clothSwitch++; 396 | if (_clothSwitch >= 750) 397 | _clothSwitch = 0; 398 | 399 | if (Character.Weapons.Current.Hash != (WeaponHash) CurrentWeapon) 400 | { 401 | var wep = Character.Weapons.Give((WeaponHash) CurrentWeapon, 9999, true, true); 402 | Character.Weapons.Select(wep); 403 | } 404 | 405 | if (!_lastJumping && IsJumping) 406 | { 407 | Character.Task.Jump(); 408 | } 409 | 410 | if (IsParachuteOpen) 411 | { 412 | if (_parachuteProp == null) 413 | { 414 | _parachuteProp = World.CreateProp(new Model(1740193300), Character.Position, 415 | Character.Rotation, false, false); 416 | _parachuteProp.FreezePosition = true; 417 | Function.Call(Hash.SET_ENTITY_COLLISION, _parachuteProp.Handle, false, 0); 418 | } 419 | Character.FreezePosition = true; 420 | Character.Position = Position - new Vector3(0, 0, 1); 421 | Character.Quaternion = Rotation; 422 | _parachuteProp.Position = Character.Position + new Vector3(0, 0, 3.7f); 423 | _parachuteProp.Quaternion = Character.Quaternion; 424 | 425 | Character.Task.PlayAnimation("skydive@parachute@first_person", "chute_idle_right", 8f, 5000, 426 | false, 8f); 427 | } 428 | else 429 | { 430 | var dest = Position; 431 | Character.FreezePosition = false; 432 | 433 | if (_parachuteProp != null) 434 | { 435 | _parachuteProp.Delete(); 436 | _parachuteProp = null; 437 | } 438 | 439 | const int threshold = 50; 440 | if (IsAiming && !IsShooting && !Character.IsInRangeOf(Position, 0.5f) && _switch%threshold == 0) 441 | { 442 | Function.Call(Hash.TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD, Character.Handle, dest.X, dest.Y, 443 | dest.Z, AimCoords.X, AimCoords.Y, AimCoords.Z, 2f, 0, 0x3F000000, 0x40800000, 1, 512, 0, 444 | (uint) FiringPattern.FullAuto); 445 | } 446 | else if (IsAiming && !IsShooting && Character.IsInRangeOf(Position, 0.5f)) 447 | { 448 | Character.Task.AimAt(AimCoords, 100); 449 | } 450 | 451 | if (!Character.IsInRangeOf(Position, 0.5f) && 452 | ((IsShooting && !_lastShooting) || 453 | (IsShooting && _lastShooting && _switch%(threshold*2) == 0))) 454 | { 455 | Function.Call(Hash.TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD, Character.Handle, dest.X, dest.Y, 456 | dest.Z, AimCoords.X, AimCoords.Y, AimCoords.Z, 2f, 1, 0x3F000000, 0x40800000, 1, 0, 0, 457 | (uint) FiringPattern.FullAuto); 458 | } 459 | else if ((IsShooting && !_lastShooting) || 460 | (IsShooting && _lastShooting && _switch%(threshold/2) == 0)) 461 | { 462 | Function.Call(Hash.TASK_SHOOT_AT_COORD, Character.Handle, AimCoords.X, AimCoords.Y, 463 | AimCoords.Z, 1500, (uint) FiringPattern.FullAuto); 464 | } 465 | 466 | if (!IsAiming && !IsShooting && !IsJumping) 467 | { 468 | switch (SyncMode) 469 | { 470 | case SynchronizationMode.Tasks: 471 | if (!Character.IsInRangeOf(Position, 0.5f)) 472 | { 473 | Character.Task.RunTo(Position, true, 500); 474 | //var targetAngle = Rotation.Z/Math.Sqrt(1 - Rotation.W*Rotation.W); 475 | //Function.Call(Hash.TASK_GO_STRAIGHT_TO_COORD, Character.Handle, Position.X, Position.Y, Position.Z, 5f, 3000, targetAngle, 0); 476 | } 477 | if (!Character.IsInRangeOf(Position, 5f)) 478 | { 479 | Character.Position = dest - new Vector3(0, 0, 1f); 480 | Character.Quaternion = Rotation; 481 | } 482 | break; 483 | case SynchronizationMode.Teleport: 484 | Character.Position = dest - new Vector3(0, 0, 1f); 485 | Character.Quaternion = Rotation; 486 | break; 487 | } 488 | } 489 | } 490 | _lastJumping = IsJumping; 491 | _lastShooting = IsShooting; 492 | _lastAiming = IsAiming; 493 | } 494 | _lastVehicle = IsInVehicle; 495 | } 496 | 497 | public void Clear() 498 | { 499 | /*if (_mainVehicle != null && Character.IsInVehicle(_mainVehicle) && Game.Player.Character.IsInVehicle(_mainVehicle)) 500 | { 501 | _playerSeat = Util.GetPedSeat(Game.Player.Character); 502 | } 503 | else 504 | { 505 | _playerSeat = -2; 506 | }*/ 507 | 508 | if (Character != null) 509 | { 510 | Character.Model.MarkAsNoLongerNeeded(); 511 | Character.Delete(); 512 | } 513 | if (_mainBlip != null) 514 | { 515 | _mainBlip.Remove(); 516 | _mainBlip = null; 517 | } 518 | if (MainVehicle != null && Util.IsVehicleEmpty(MainVehicle)) 519 | { 520 | MainVehicle.Model.MarkAsNoLongerNeeded(); 521 | MainVehicle.Delete(); 522 | } 523 | if (_parachuteProp != null) 524 | { 525 | _parachuteProp.Delete(); 526 | _parachuteProp = null; 527 | } 528 | } 529 | } 530 | } -------------------------------------------------------------------------------- /Client/Util.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Windows.Forms; 6 | using System.Xml.Serialization; 7 | using GTA; 8 | using GTA.Math; 9 | using GTA.Native; 10 | 11 | namespace GTACoOp 12 | { 13 | public static class Util 14 | { 15 | public static int GetStationId() 16 | { 17 | if (!Game.Player.Character.IsInVehicle()) return -1; 18 | return Function.Call(Hash.GET_PLAYER_RADIO_STATION_INDEX); 19 | } 20 | 21 | public static string GetStationName(int id) 22 | { 23 | return Function.Call(Hash.GET_RADIO_STATION_NAME, id); 24 | } 25 | 26 | public static int GetTrackId() 27 | { 28 | if (!Game.Player.Character.IsInVehicle()) return -1; 29 | return Function.Call(Hash.GET_AUDIBLE_MUSIC_TRACK_TEXT_ID); 30 | } 31 | 32 | public static bool IsVehicleEmpty(Vehicle veh) 33 | { 34 | if (veh == null) return true; 35 | if (!veh.IsSeatFree(VehicleSeat.Driver)) return false; 36 | for (int i = 0; i < veh.PassengerSeats; i++) 37 | { 38 | if (!veh.IsSeatFree((VehicleSeat)i)) 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | public static Dictionary GetVehicleMods(Vehicle veh) 45 | { 46 | var dict = new Dictionary(); 47 | for (int i = 0; i < 50; i++) 48 | { 49 | dict.Add(i, veh.GetMod((VehicleMod)i)); 50 | } 51 | return dict; 52 | } 53 | 54 | public static Dictionary GetPlayerProps(Ped ped) 55 | { 56 | var props = new Dictionary(); 57 | for (int i = 0; i < 15; i++) 58 | { 59 | var mod = Function.Call(Hash.GET_PED_DRAWABLE_VARIATION, ped.Handle, i); 60 | if (mod == -1) continue; 61 | props.Add(i, mod); 62 | } 63 | return props; 64 | } 65 | 66 | public static int GetPedSeat(Ped ped) 67 | { 68 | if (ped == null || !ped.IsInVehicle()) return -3; 69 | if (ped.CurrentVehicle.GetPedOnSeat(VehicleSeat.Driver) == ped) return (int)VehicleSeat.Driver; 70 | for (int i = 0; i < ped.CurrentVehicle.PassengerSeats; i++) 71 | { 72 | if (ped.CurrentVehicle.GetPedOnSeat((VehicleSeat)i) == ped) 73 | return i; 74 | } 75 | return -3; 76 | } 77 | 78 | public static int GetFreePassengerSeat(Vehicle veh) 79 | { 80 | if (veh == null) return -3; 81 | for (int i = 0; i < veh.PassengerSeats; i++) 82 | { 83 | if (veh.IsSeatFree((VehicleSeat)i)) 84 | return i; 85 | } 86 | return -3; 87 | } 88 | 89 | public static PlayerSettings ReadSettings(string path) 90 | { 91 | var ser = new XmlSerializer(typeof(PlayerSettings)); 92 | 93 | PlayerSettings settings = null; 94 | 95 | if (File.Exists(path)) 96 | { 97 | using (var stream = File.OpenRead(path)) settings = (PlayerSettings)ser.Deserialize(stream); 98 | 99 | using (var stream = new FileStream(path, File.Exists(path) ? FileMode.Truncate : FileMode.Create, FileAccess.ReadWrite)) ser.Serialize(stream, settings); 100 | } 101 | else 102 | { 103 | using (var stream = File.OpenWrite(path)) ser.Serialize(stream, settings = new PlayerSettings()); 104 | } 105 | 106 | return settings; 107 | } 108 | 109 | public static void SaveSettings(string path) 110 | { 111 | var ser = new XmlSerializer(typeof(PlayerSettings)); 112 | using (var stream = new FileStream(path, File.Exists(path) ? FileMode.Truncate : FileMode.Create, FileAccess.ReadWrite)) ser.Serialize(stream, Main.PlayerSettings); 113 | } 114 | 115 | public static Vector3 GetLastWeaponImpact(Ped ped) 116 | { 117 | var coord = new OutputArgument(); 118 | if (!Function.Call(Hash.GET_PED_LAST_WEAPON_IMPACT_COORD, ped.Handle, coord)) 119 | { 120 | return new Vector3(); 121 | } 122 | return coord.GetResult(); 123 | } 124 | 125 | public static Quaternion LerpQuaternion(Quaternion start, Quaternion end, float speed) 126 | { 127 | return new Quaternion() 128 | { 129 | X = start.X + (end.X - start.X) * speed, 130 | Y = start.Y + (end.Y - start.Y) * speed, 131 | Z = start.Z + (end.Z - start.Z) * speed, 132 | W = start.W + (end.W - start.W) * speed, 133 | }; 134 | } 135 | 136 | public static Vector3 LerpVector(Vector3 start, Vector3 end, float speed) 137 | { 138 | return new Vector3() 139 | { 140 | X = start.X + (end.X - start.X) * speed, 141 | Y = start.Y + (end.Y - start.Y) * speed, 142 | Z = start.Z + (end.Z - start.Z) * speed, 143 | }; 144 | } 145 | 146 | public static Vector3 QuaternionToEuler(Quaternion quat) 147 | { 148 | //heading = atan2(2*qy*qw-2*qx*qz , 1 - 2*qy2 - 2*qz2) (yaw) 149 | //attitude = asin(2 * qx * qy + 2 * qz * qw) (pitch) 150 | //bank = atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx2 - 2 * qz2) (roll) 151 | 152 | return new Vector3() 153 | { 154 | X = (float)Math.Asin(2 * quat.X * quat.Y + 2 *quat.Z * quat.W), 155 | Y = (float)Math.Atan2(2 * quat.X * quat.W - 2 * quat.Y * quat.Z, 1 - 2 * quat.X*quat.X - 2 * quat.Z * quat.Z), 156 | Z = (float)Math.Atan2(2*quat.Y*quat.W - 2*quat.X*quat.Z, 1 - 2*quat.Y*quat.Y - 2*quat.Z * quat.Z), 157 | }; 158 | 159 | /*except when qx*qy + qz*qw = 0.5 (north pole) 160 | which gives: 161 | heading = 2 * atan2(x,w) 162 | bank = 0 163 | 164 | and when qx*qy + qz*qw = -0.5 (south pole) 165 | which gives: 166 | heading = -2 * atan2(x,w) 167 | bank = 0 */ 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /Client/VehicleData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using GTA.Math; 3 | using ProtoBuf; 4 | 5 | namespace GTACoOp 6 | { 7 | public enum PacketType 8 | { 9 | VehiclePositionData = 0, 10 | ChatData = 1, 11 | PlayerDisconnect = 2, 12 | PedPositionData = 3, 13 | NpcVehPositionData = 4, 14 | NpcPedPositionData = 5, 15 | WorldSharingStop = 6, 16 | DiscoveryResponse = 7, 17 | ConnectionRequest = 8, 18 | NativeCall = 9, 19 | NativeResponse = 10, 20 | PlayerKilled = 11, 21 | NativeTick = 12, 22 | NativeTickRecall = 13, 23 | NativeOnDisconnect = 14, 24 | NativeOnDisconnectRecall = 15, 25 | } 26 | 27 | public enum ScriptVersion 28 | { 29 | Unknown = 0, 30 | VERSION_0_6 = 1, 31 | VERSION_0_6_1 = 2, 32 | VERSION_0_7 = 3, 33 | VERSION_0_8_1 = 4, 34 | VERSION_0_9 = 5, 35 | } 36 | 37 | [ProtoContract] 38 | public class DiscoveryResponse 39 | { 40 | [ProtoMember(1)] 41 | public string ServerName { get; set; } 42 | [ProtoMember(2)] 43 | public int MaxPlayers { get; set; } 44 | [ProtoMember(3)] 45 | public int PlayerCount { get; set; } 46 | [ProtoMember(4)] 47 | public bool PasswordProtected { get; set; } 48 | [ProtoMember(5)] 49 | public int Port { get; set; } 50 | [ProtoMember(6)] 51 | public string Gamemode { get; set; } 52 | } 53 | 54 | [ProtoContract] 55 | public class ConnectionRequest 56 | { 57 | [ProtoMember(1)] 58 | public string Name { get; set; } 59 | 60 | [ProtoMember(2)] 61 | public string Password { get; set; } 62 | 63 | [ProtoMember(3)] 64 | public string DisplayName { get; set; } 65 | 66 | [ProtoMember(4)] 67 | public int GameVersion { get; set; } 68 | 69 | [ProtoMember(5)] 70 | public byte ScriptVersion { get; set; } 71 | } 72 | 73 | [ProtoContract] 74 | public class VehicleData 75 | { 76 | [ProtoMember(1)] 77 | public long Id { get; set; } 78 | [ProtoMember(2)] 79 | public string Name { get; set; } 80 | 81 | [ProtoMember(3)] 82 | public int VehicleModelHash { get; set; } 83 | [ProtoMember(4)] 84 | public int PedModelHash { get; set; } 85 | [ProtoMember(5)] 86 | public int PrimaryColor { get; set; } 87 | [ProtoMember(6)] 88 | public int SecondaryColor { get; set; } 89 | 90 | [ProtoMember(7)] 91 | public LVector3 Position { get; set; } 92 | [ProtoMember(8)] 93 | public LQuaternion Quaternion { get; set; } 94 | 95 | [ProtoMember(9)] 96 | public int VehicleSeat { get; set; } 97 | 98 | [ProtoMember(10)] 99 | public int VehicleHealth { get; set; } 100 | 101 | [ProtoMember(11)] 102 | public int PlayerHealth { get; set; } 103 | 104 | [ProtoMember(12)] 105 | public float Latency { get; set; } 106 | 107 | [ProtoMember(13)] 108 | public Dictionary VehicleMods { get; set; } 109 | 110 | [ProtoMember(14)] 111 | public bool IsPressingHorn { get; set; } 112 | 113 | [ProtoMember(15)] 114 | public bool IsSirenActive { get; set; } 115 | 116 | [ProtoMember(16)] 117 | public float Speed { get; set; } 118 | } 119 | 120 | [ProtoContract] 121 | public class PedData 122 | { 123 | [ProtoMember(1)] 124 | public long Id { get; set; } 125 | [ProtoMember(2)] 126 | public string Name { get; set; } 127 | 128 | [ProtoMember(3)] 129 | public int PedModelHash { get; set; } 130 | 131 | [ProtoMember(4)] 132 | public LVector3 Position { get; set; } 133 | [ProtoMember(5)] 134 | public LQuaternion Quaternion { get; set; } 135 | 136 | [ProtoMember(6)] 137 | public bool IsJumping { get; set; } 138 | [ProtoMember(7)] 139 | public bool IsShooting { get; set; } 140 | [ProtoMember(8)] 141 | public bool IsAiming { get; set; } 142 | [ProtoMember(9)] 143 | public LVector3 AimCoords { get; set; } 144 | [ProtoMember(10)] 145 | public int WeaponHash { get; set; } 146 | 147 | [ProtoMember(11)] 148 | public int PlayerHealth { get; set; } 149 | 150 | [ProtoMember(12)] 151 | public float Latency { get; set; } 152 | 153 | [ProtoMember(13)] 154 | public Dictionary PedProps { get; set; } 155 | 156 | [ProtoMember(14)] 157 | public bool IsParachuteOpen { get; set; } 158 | } 159 | 160 | [ProtoContract] 161 | public class PlayerDisconnect 162 | { 163 | [ProtoMember(1)] 164 | public long Id { get; set; } 165 | } 166 | 167 | [ProtoContract] 168 | public class LVector3 169 | { 170 | [ProtoMember(1)] 171 | public float X { get; set; } 172 | [ProtoMember(2)] 173 | public float Y { get; set; } 174 | [ProtoMember(3)] 175 | public float Z { get; set; } 176 | 177 | public Vector3 ToVector() 178 | { 179 | return new Vector3(X, Y, Z); 180 | } 181 | } 182 | 183 | [ProtoContract] 184 | public class LQuaternion 185 | { 186 | [ProtoMember(1)] 187 | public float X { get; set; } 188 | [ProtoMember(2)] 189 | public float Y { get; set; } 190 | [ProtoMember(3)] 191 | public float Z { get; set; } 192 | [ProtoMember(4)] 193 | public float W { get; set; } 194 | 195 | public Quaternion ToQuaternion() 196 | { 197 | return new Quaternion(X, Y, Z, W); 198 | } 199 | } 200 | 201 | public static class VectorExtensions 202 | { 203 | public static LVector3 ToLVector(this Vector3 vec) 204 | { 205 | return new LVector3() 206 | { 207 | X = vec.X, 208 | Y = vec.Y, 209 | Z = vec.Z, 210 | }; 211 | } 212 | 213 | public static LQuaternion ToLQuaternion(this Quaternion vec) 214 | { 215 | return new LQuaternion() 216 | { 217 | X = vec.X, 218 | Y = vec.Y, 219 | Z = vec.Z, 220 | W = vec.W, 221 | }; 222 | } 223 | } 224 | } -------------------------------------------------------------------------------- /Client/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /GTACoOp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GTACoOp", "Client\GTACoOp.csproj", "{1BC495C9-DC44-478A-9E16-3FC482A8B850}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GTAServer", "Server\GTAServer.csproj", "{559EE224-BF7B-49D8-9CEE-11E6BA71FE4E}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdminTools", "AdminTools\AdminTools.csproj", "{158CCEB2-E6EC-457B-BA61-E448BD6B0F40}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Race", "Race\Race.csproj", "{988CD1D8-48ED-4C19-8953-79FAFDBB34DD}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {1BC495C9-DC44-478A-9E16-3FC482A8B850}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {1BC495C9-DC44-478A-9E16-3FC482A8B850}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {1BC495C9-DC44-478A-9E16-3FC482A8B850}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {1BC495C9-DC44-478A-9E16-3FC482A8B850}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {559EE224-BF7B-49D8-9CEE-11E6BA71FE4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {559EE224-BF7B-49D8-9CEE-11E6BA71FE4E}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {559EE224-BF7B-49D8-9CEE-11E6BA71FE4E}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {559EE224-BF7B-49D8-9CEE-11E6BA71FE4E}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {158CCEB2-E6EC-457B-BA61-E448BD6B0F40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {158CCEB2-E6EC-457B-BA61-E448BD6B0F40}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {158CCEB2-E6EC-457B-BA61-E448BD6B0F40}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {158CCEB2-E6EC-457B-BA61-E448BD6B0F40}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {988CD1D8-48ED-4C19-8953-79FAFDBB34DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {988CD1D8-48ED-4C19-8953-79FAFDBB34DD}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {988CD1D8-48ED-4C19-8953-79FAFDBB34DD}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {988CD1D8-48ED-4C19-8953-79FAFDBB34DD}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [GTA Co-Op](http://www.gtampco-op.cf/) [![Github All Releases](https://img.shields.io/github/downloads/Guad/GTACoop/total.svg)]() 2 | 3 | An abandoned (still works) online co-op modification for GTA5. Does not use Rockstar's Online code. 4 | 5 | If you have questions be sure to check the [wiki](https://github.com/Guad/GTACoop/wiki) first. 6 | 7 | ![GitHub license](https://img.shields.io/badge/license-AGPL-blue.svg) 8 | Copyright (C) 2016 Guad 9 | 10 | [![GitHub contributors](https://img.shields.io/github/contributors/Guad/GTACoop.svg)]() 11 | [![Join the chat at https://gitter.im/Bluscream/GTACoop](https://badges.gitter.im/Bluscream/GTACoop.svg)](https://gitter.im/Bluscream/GTACoop?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 12 | -------------------------------------------------------------------------------- /Race/Gamemode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using System.Xml.Serialization; 9 | using GTAServer; 10 | 11 | namespace Race 12 | { 13 | public class Opponent 14 | { 15 | public Opponent(Client c) 16 | { 17 | Client = c; 18 | CheckpointsPassed = 0; 19 | } 20 | 21 | public Client Client { get; set; } 22 | public int CheckpointsPassed { get; set; } 23 | public bool HasFinished { get; set; } 24 | public bool HasStarted { get; set; } 25 | public int Vehicle { get; set; } 26 | public int Blip { get; set; } 27 | } 28 | 29 | public class Gamemode : ServerScript 30 | { 31 | public bool IsRaceOngoing { get; set; } 32 | public List Opponents { get; set; } 33 | public Race CurrentRace { get; set; } 34 | public List AvailableRaces { get; set; } 35 | public List CurrentRaceCheckpoints { get; set; } 36 | public Dictionary RememberedBlips { get; set; } 37 | public DateTime RaceStart { get; set; } 38 | 39 | 40 | // Voting 41 | public DateTime VoteStart { get; set; } 42 | public List Voters { get; set; } 43 | public Dictionary Votes { get; set; } 44 | public Dictionary AvailableChoices { get; set; } 45 | 46 | public override void Start() 47 | { 48 | AvailableRaces = new List(); 49 | Opponents = new List(); 50 | RememberedBlips = new Dictionary(); 51 | CurrentRaceCheckpoints = new List(); 52 | LoadRaces(); 53 | 54 | Console.WriteLine("Race gamemode started! Loaded " + AvailableRaces.Count + " races."); 55 | 56 | StartVote(); 57 | } 58 | 59 | public bool IsVoteActive() 60 | { 61 | return DateTime.Now.Subtract(VoteStart).TotalSeconds < 60; 62 | } 63 | 64 | public override void OnTick() 65 | { 66 | if (!IsRaceOngoing) return; 67 | 68 | lock (Opponents) 69 | { 70 | lock (CurrentRaceCheckpoints) 71 | foreach (var opponent in Opponents) 72 | { 73 | if (opponent.HasFinished || !opponent.HasStarted) continue; 74 | if (CurrentRaceCheckpoints.Any() && opponent.Client.LastKnownPosition.IsInRangeOf(CurrentRaceCheckpoints[opponent.CheckpointsPassed], 10f)) 75 | { 76 | opponent.CheckpointsPassed++; 77 | if (opponent.CheckpointsPassed >= CurrentRaceCheckpoints.Count) 78 | { 79 | if (Opponents.All(op => !op.HasFinished)) 80 | { 81 | var t = new Thread((ThreadStart) delegate 82 | { 83 | Thread.Sleep(10000); 84 | Program.ServerInstance.SendChatMessageToAll("Vote for next map will start in 60 seconds!"); 85 | Thread.Sleep(30000); 86 | Program.ServerInstance.SendChatMessageToAll("Vote for next map will start in 30 seconds!"); 87 | Thread.Sleep(30000); 88 | if (!IsVoteActive()) 89 | StartVote(); 90 | }); 91 | t.Start(); 92 | } 93 | 94 | opponent.HasFinished = true; 95 | var pos = Opponents.Count(o => o.HasFinished); 96 | var suffix = pos.ToString().EndsWith("1") 97 | ? "st" 98 | : pos.ToString().EndsWith("2") ? "nd" : pos.ToString().EndsWith("3") ? "rd" : "th"; 99 | Program.ServerInstance.SendNotificationToAll("~h~" + opponent.Client.DisplayName + "~h~ has finished " + pos + suffix); 100 | Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0x45FF974EEE1C8734, opponent.Blip, 0); 101 | Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER"); 102 | Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR"); 103 | continue; 104 | } 105 | 106 | Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0xAE2AF67E9D9AF65D, opponent.Blip, 107 | CurrentRaceCheckpoints[opponent.CheckpointsPassed].X, 108 | CurrentRaceCheckpoints[opponent.CheckpointsPassed].Y, 109 | CurrentRaceCheckpoints[opponent.CheckpointsPassed].Z); 110 | 111 | Program.ServerInstance.SetNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER", 112 | 0x28477EC23D892089, 1, CurrentRaceCheckpoints[opponent.CheckpointsPassed], new Vector3(), new Vector3(), 113 | new Vector3() { X = 10f, Y = 10f, Z = 2f }, 241, 247, 57, 180, false, false, 2, false, false, 114 | false, false); 115 | 116 | if (CurrentRaceCheckpoints.Count > opponent.CheckpointsPassed+1) 117 | { 118 | var nextCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]; 119 | var curCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; 120 | 121 | if (nextCp != null && curCp != null) 122 | { 123 | Vector3 dir = nextCp.Subtract(curCp); 124 | dir = dir.Normalize(); 125 | 126 | Program.ServerInstance.SetNativeCallOnTickForPlayer(opponent.Client, 127 | "RACE_CHECKPOINT_MARKER_DIR", 128 | 0x28477EC23D892089, 20, curCp.Subtract(new Vector3() {X = 0f, Y = 0f, Z = -2f}), dir, 129 | new Vector3() {X = 60f, Y = 0f, Z = 0f}, 130 | new Vector3() {X = 4f, Y = 4f, Z = 4f}, 87, 193, 250, 200, false, false, 2, false, 131 | false, 132 | false, false); 133 | } 134 | } 135 | else 136 | { 137 | Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR"); 138 | } 139 | } 140 | } 141 | } 142 | 143 | } 144 | 145 | public override bool OnPlayerDisconnect(Client player) 146 | { 147 | Opponent curOp = Opponents.FirstOrDefault(op => op.Client == player); 148 | if (curOp == null) return true; 149 | 150 | if (RememberedBlips.ContainsKey(player.NetConnection.RemoteUniqueIdentifier)) 151 | RememberedBlips[player.NetConnection.RemoteUniqueIdentifier] = curOp.Blip; 152 | else 153 | RememberedBlips.Add(player.NetConnection.RemoteUniqueIdentifier, curOp.Blip); 154 | 155 | if (curOp.Vehicle != 0) 156 | { 157 | Program.ServerInstance.SendNativeCallToPlayer(player, 0xAD738C3085FE7E11, curOp.Vehicle, true, false); 158 | Program.ServerInstance.SendNativeCallToPlayer(player, 0xAE3CBE5BF394C9C9, curOp.Vehicle); 159 | } 160 | 161 | if (curOp.Blip != 0) 162 | { 163 | Program.ServerInstance.SendNativeCallToPlayer(player, 0x45FF974EEE1C8734, curOp.Blip, 0); 164 | } 165 | 166 | lock (Opponents) Opponents.Remove(curOp); 167 | return true; 168 | } 169 | 170 | public override bool OnChatMessage(Client sender, string message) 171 | { 172 | if (message == "/votemap" && !IsVoteActive() && (!IsRaceOngoing || DateTime.UtcNow.Subtract(RaceStart).TotalSeconds > 60)) 173 | { 174 | StartVote(); 175 | return false; 176 | } 177 | else if (message.StartsWith("/vote")) 178 | { 179 | if (DateTime.Now.Subtract(VoteStart).TotalSeconds > 60) 180 | { 181 | Program.ServerInstance.SendChatMessageToPlayer(sender, "No current vote is in progress."); 182 | return false; 183 | } 184 | 185 | var args = message.Split(); 186 | 187 | if (args.Length <= 1) 188 | { 189 | Program.ServerInstance.SendChatMessageToPlayer(sender, "USAGE", "/vote [id]"); 190 | return false; 191 | } 192 | 193 | if (Voters.Contains(sender)) 194 | { 195 | Program.ServerInstance.SendChatMessageToPlayer(sender, "ERROR", "You have already voted!"); 196 | return false; 197 | } 198 | 199 | int choice; 200 | if (!int.TryParse(args[1], out choice) || choice <= 0 || choice > AvailableChoices.Count) 201 | { 202 | Program.ServerInstance.SendChatMessageToPlayer(sender, "USAGE", "/vote [id]"); 203 | return false; 204 | } 205 | 206 | Votes[choice]++; 207 | Program.ServerInstance.SendChatMessageToPlayer(sender, "You have voted for " + AvailableChoices[choice].Name); 208 | Voters.Add(sender); 209 | return false; 210 | } 211 | else if (message == "/q") 212 | { 213 | Opponent curOp = Opponents.FirstOrDefault(op => op.Client == sender); 214 | 215 | if (curOp != null) 216 | { 217 | if (curOp.Blip != 0) 218 | { 219 | Program.ServerInstance.SendNativeCallToPlayer(sender, 0x45FF974EEE1C8734, curOp.Blip, 0); 220 | //Program.ServerInstance.SendNativeCallToPlayer(sender, 0x86A652570E5F25DD, new PointerArgumentInt() {Data = curOp.Blip}); 221 | } 222 | 223 | lock (Opponents) Opponents.Remove(curOp); 224 | } 225 | 226 | Program.ServerInstance.KickPlayer(sender, "requested"); 227 | return false; 228 | } 229 | return true; 230 | } 231 | 232 | public override bool OnPlayerConnect(Client player) 233 | { 234 | Program.ServerInstance.SetNativeCallOnTickForPlayer(player, "RACE_DISABLE_VEHICLE_EXIT", 0xFE99B66D079CF6BC, 0, 75, true); 235 | Program.ServerInstance.SendNotificationToPlayer(player, "~r~IMPORTANT~w~~n~" + "Quit the server using the ~h~/q~h~ command to remove the blip."); 236 | 237 | if (IsRaceOngoing) 238 | { 239 | SetUpPlayerForRace(player, CurrentRace, false, 0); 240 | } 241 | 242 | if (DateTime.Now.Subtract(VoteStart).TotalSeconds < 60) 243 | { 244 | Program.ServerInstance.SendNotificationToPlayer(player, GetVoteHelpString()); 245 | } 246 | 247 | if (RememberedBlips.ContainsKey(player.NetConnection.RemoteUniqueIdentifier)) 248 | { 249 | Opponents.Add(new Opponent(player) {Blip = RememberedBlips[player.NetConnection.RemoteUniqueIdentifier]}); 250 | } 251 | return true; 252 | } 253 | 254 | private int LoadRaces() 255 | { 256 | int counter = 0; 257 | if (!Directory.Exists("races")) return 0; 258 | foreach (string path in Directory.GetFiles("races", "*.xml")) 259 | { 260 | XmlSerializer serializer = new XmlSerializer(typeof(Race)); 261 | StreamReader file = new StreamReader(path); 262 | var raceout = (Race)serializer.Deserialize(file); 263 | file.Close(); 264 | AvailableRaces.Add(raceout); 265 | counter++; 266 | } 267 | return counter; 268 | } 269 | 270 | private void StartRace(Race race) 271 | { 272 | race = new Race(race); 273 | //Game.FadeScreenOut(500); 274 | 275 | CurrentRace = race; 276 | 277 | /*if (_raceSettings["Laps"] > 1) 278 | { 279 | _totalLaps = race.Checkpoints.Length; 280 | List tmpCheckpoints = new List(); 281 | for (int i = 0; i < _raceSettings["Laps"]; i++) 282 | { 283 | tmpCheckpoints.AddRange(race.Checkpoints); 284 | } 285 | _currentRace.Checkpoints = tmpCheckpoints.ToArray(); 286 | }*/ 287 | 288 | Opponents.ForEach(op => 289 | { 290 | op.HasFinished = false; 291 | op.CheckpointsPassed = 0; 292 | }); 293 | 294 | 295 | lock (Program.ServerInstance.Clients) 296 | for (int i = 0; i < Program.ServerInstance.Clients.Count; i++) 297 | { 298 | SetUpPlayerForRace(Program.ServerInstance.Clients[i], CurrentRace, true, i); 299 | } 300 | 301 | CurrentRaceCheckpoints = race.Checkpoints.ToList(); 302 | RaceStart = DateTime.UtcNow; 303 | 304 | Console.WriteLine("RACE: Starting race " + race.Name); 305 | 306 | var t = new Thread((ThreadStart) delegate 307 | { 308 | Thread.Sleep(10000); 309 | Program.ServerInstance.SendNotificationToAll("3"); // I should probably automate this 310 | Thread.Sleep(1000); 311 | Program.ServerInstance.SendNotificationToAll("2"); 312 | Thread.Sleep(1000); 313 | Program.ServerInstance.SendNotificationToAll("1"); 314 | Thread.Sleep(1000); 315 | Program.ServerInstance.SendNotificationToAll("Go!"); 316 | IsRaceOngoing = true; 317 | 318 | 319 | lock (Opponents) 320 | foreach (var opponent in Opponents) 321 | { 322 | Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0x428CA6DBD1094446, opponent.Vehicle, false); 323 | opponent.HasStarted = true; 324 | } 325 | }); 326 | t.Start(); 327 | } 328 | 329 | private void EndRace() 330 | { 331 | IsRaceOngoing = false; 332 | CurrentRace = null; 333 | 334 | foreach (var opponent in Opponents) 335 | { 336 | opponent.CheckpointsPassed = 0; 337 | opponent.HasFinished = true; 338 | opponent.HasStarted = false; 339 | 340 | if (opponent.Blip != 0) 341 | { 342 | Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0x45FF974EEE1C8734, opponent.Blip, 0); 343 | } 344 | } 345 | 346 | Program.ServerInstance.RecallNativeCallOnTickForAllPlayers("RACE_CHECKPOINT_MARKER"); 347 | Program.ServerInstance.RecallNativeCallOnTickForAllPlayers("RACE_CHECKPOINT_MARKER_DIR"); 348 | 349 | CurrentRaceCheckpoints.Clear(); 350 | } 351 | 352 | private Random randGen = new Random(); 353 | private void SetUpPlayerForRace(Client client, Race race, bool freeze, int spawnpoint) 354 | { 355 | if (race == null) return; 356 | 357 | var selectedModel = unchecked((int)((uint)race.AvailableVehicles[randGen.Next(race.AvailableVehicles.Length)])); 358 | var position = race.SpawnPoints[spawnpoint % race.SpawnPoints.Length].Position; 359 | var heading = race.SpawnPoints[spawnpoint % race.SpawnPoints.Length].Heading; 360 | Program.ServerInstance.SendNativeCallToPlayer(client, 0x06843DA7060A026B, new LocalPlayerArgument(), 361 | position.X, position.Y, position.Z, 0, 0, 0, 1); 362 | 363 | if (race.Checkpoints.Length >= 2) 364 | { 365 | Vector3 dir = race.Checkpoints[1].Subtract(race.Checkpoints[0]); 366 | dir = dir.Normalize(); 367 | 368 | Program.ServerInstance.SetNativeCallOnTickForPlayer(client, "RACE_CHECKPOINT_MARKER_DIR", 369 | 0x28477EC23D892089, 20, race.Checkpoints[0].Subtract(new Vector3() { X = 0f, Y = 0f, Z = -2f }), dir, new Vector3() { X = 60f, Y = 0f, Z = 0f }, 370 | new Vector3() { X = 4f, Y = 4f, Z = 4f }, 87, 193, 250, 200, false, false, 2, false, false, 371 | false, false); 372 | } 373 | 374 | 375 | Program.ServerInstance.SetNativeCallOnTickForPlayer(client, "RACE_CHECKPOINT_MARKER", 376 | 0x28477EC23D892089, 1, race.Checkpoints[0], new Vector3(), new Vector3(), 377 | new Vector3() { X = 10f, Y = 10f, Z = 2f }, 241, 247, 57, 180, false, false, 2, false, false, 378 | false, false); 379 | 380 | 381 | var nt = new Thread((ThreadStart)delegate 382 | { 383 | SetPlayerInVehicle(client, selectedModel, position, heading, freeze); 384 | }); 385 | nt.Start(); 386 | 387 | Opponent curOp = Opponents.FirstOrDefault(op => op.Client == client); 388 | if (curOp == null || curOp.Blip == 0) 389 | { 390 | Program.ServerInstance.GetNativeCallFromPlayer(client, "start_blip", 0x5A039BB0BCA604B6, 391 | new IntArgument(), // ADD_BLIP_FOR_COORD 392 | delegate (object o) 393 | { 394 | lock (Opponents) 395 | { 396 | Opponent secOp = Opponents.FirstOrDefault(op => op.Client == client); 397 | 398 | if (secOp != null) 399 | { 400 | secOp.Blip = (int)o; 401 | } 402 | else 403 | Opponents.Add(new Opponent(client) { Blip = (int)o }); 404 | } 405 | }, race.Checkpoints[0].X, race.Checkpoints[0].Y, race.Checkpoints[0].Z); 406 | } 407 | else 408 | { 409 | Program.ServerInstance.SendNativeCallToPlayer(client, 0x45FF974EEE1C8734, curOp.Blip, 255); 410 | Program.ServerInstance.SendNativeCallToPlayer(client, 0xAE2AF67E9D9AF65D, curOp.Blip, race.Checkpoints[0].X, race.Checkpoints[0].Y, race.Checkpoints[0].Z); 411 | } 412 | } 413 | 414 | /*private int CalculatePlayerPositionInRace(Client player) 415 | { 416 | int output = 0; 417 | int playerCheckpoint = _currentRace.Checkpoints.Length - _checkpoints.Count; 418 | 419 | int beforeYou = _rivalCheckpointStatus.Count(tuple => tuple.Item2 > playerCheckpoint); 420 | output += beforeYou; 421 | 422 | var samePosAsYou = _rivalCheckpointStatus.Where(tuple => tuple.Item2 == playerCheckpoint); 423 | output += 424 | samePosAsYou.Count( 425 | tuple => 426 | (_currentRace.Checkpoints[playerCheckpoint] - tuple.Item1.Vehicle.Position).Length() < 427 | (_currentRace.Checkpoints[playerCheckpoint] - Game.Player.Character.Position).Length()); 428 | 429 | return output; 430 | }*/ 431 | 432 | private void SetPlayerInVehicle(Client player, int model, Vector3 pos, float heading, bool freeze) 433 | { 434 | Program.ServerInstance.SetNativeCallOnTickForPlayer(player, "RACE_REQUEST_MODEL", 0x963D27A58DF860AC, model); 435 | Thread.Sleep(5000); 436 | Program.ServerInstance.RecallNativeCallOnTickForPlayer(player, "RACE_REQUEST_MODEL"); 437 | 438 | Program.ServerInstance.GetNativeCallFromPlayer(player, "spawn", 0xAF35D0D2583051B0, new IntArgument(), 439 | delegate (object o) 440 | { 441 | Program.ServerInstance.SendNativeCallToPlayer(player, 0xF75B0D629E1C063D, new LocalPlayerArgument(), (int)o, -1); 442 | if (freeze) 443 | Program.ServerInstance.SendNativeCallToPlayer(player, 0x428CA6DBD1094446, (int)o, true); 444 | 445 | Opponent inOp = Opponents.FirstOrDefault(op => op.Client == player); 446 | 447 | lock (Opponents) 448 | { 449 | if (inOp != null) 450 | { 451 | inOp.Vehicle = (int)o; 452 | inOp.HasStarted = true; 453 | } 454 | else 455 | Opponents.Add(new Opponent(player) { Vehicle = (int)o, HasStarted = true}); 456 | } 457 | 458 | Program.ServerInstance.SendNativeCallToPlayer(player, 0xE532F5D78798DAAB, model); 459 | }, model, pos.X, pos.Y, pos.Z, heading, false, false); 460 | } 461 | 462 | public void StartVote() 463 | { 464 | var pickedRaces = new List(); 465 | var racePool = new List(AvailableRaces); 466 | var rand = new Random(); 467 | 468 | for (int i = 0; i < Math.Min(9, AvailableRaces.Count); i++) 469 | { 470 | var pick = rand.Next(racePool.Count); 471 | pickedRaces.Add(racePool[pick]); 472 | racePool.RemoveAt(pick); 473 | } 474 | 475 | Votes = new Dictionary(); 476 | Voters = new List(); 477 | AvailableChoices = new Dictionary(); 478 | 479 | var build = new StringBuilder(); 480 | build.Append("Type /vote [id] to vote for the next race! The options are:"); 481 | 482 | var counter = 1; 483 | foreach (var race in pickedRaces) 484 | { 485 | build.Append("\n" + counter + ": " + race.Name); 486 | Votes.Add(counter, 0); 487 | AvailableChoices.Add(counter, race); 488 | counter++; 489 | } 490 | 491 | VoteStart = DateTime.Now; 492 | Program.ServerInstance.SendNotificationToAll(build.ToString()); 493 | 494 | var t = new Thread((ThreadStart)delegate 495 | { 496 | Thread.Sleep(60*1000); 497 | EndRace(); 498 | var raceWon = AvailableChoices[Votes.OrderByDescending(pair => pair.Value).ToList()[0].Key]; 499 | Program.ServerInstance.SendNotificationToAll(raceWon.Name + " has won the vote!"); 500 | 501 | Thread.Sleep(1000); 502 | StartRace(raceWon); 503 | }); 504 | t.Start(); 505 | } 506 | 507 | private string GetVoteHelpString() 508 | { 509 | if (DateTime.Now.Subtract(VoteStart).TotalSeconds > 60) 510 | return null; 511 | 512 | var build = new StringBuilder(); 513 | build.Append("Type /vote [id] to vote for the next race! The options are:"); 514 | 515 | foreach (var race in AvailableChoices) 516 | { 517 | build.Append("\n" + race.Key + ": " + race.Value.Name); 518 | } 519 | 520 | return build.ToString(); 521 | } 522 | } 523 | 524 | public static class RangeExtension 525 | { 526 | public static bool IsInRangeOf(this Vector3 center, Vector3 dest, float radius) 527 | { 528 | return center.Subtract(dest).Length() < radius; 529 | } 530 | 531 | public static Vector3 Subtract(this Vector3 left, Vector3 right) 532 | { 533 | return new Vector3() 534 | { 535 | X = left.X - right.X, 536 | Y = left.Y - right.Y, 537 | Z = left.Z - right.Z, 538 | }; 539 | } 540 | 541 | public static float Length(this Vector3 vect) 542 | { 543 | return (float) Math.Sqrt((vect.X*vect.X) + (vect.Y*vect.Y) + (vect.Z*vect.Z)); 544 | } 545 | 546 | public static Vector3 Normalize(this Vector3 vect) 547 | { 548 | float length = vect.Length(); 549 | if (length == 0) return vect; 550 | 551 | float num = 1/length; 552 | 553 | return new Vector3() 554 | { 555 | X = vect.X * num, 556 | Y = vect.Y * num, 557 | Z = vect.Z * num, 558 | }; 559 | } 560 | } 561 | } 562 | -------------------------------------------------------------------------------- /Race/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Freeroam")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Freeroam")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("988cd1d8-48ed-4c19-8953-79fafdbb34dd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Race/Race.cs: -------------------------------------------------------------------------------- 1 | using GTAServer; 2 | 3 | 4 | namespace Race 5 | { 6 | public class Race 7 | { 8 | public Vector3[] Checkpoints; 9 | public SpawnPoint[] SpawnPoints; 10 | public VehicleHash[] AvailableVehicles; 11 | public bool LapsAvailable = true; 12 | public Vector3 Trigger; 13 | 14 | public string Name; 15 | public string Description; 16 | 17 | public Race() { } 18 | 19 | public Race(Race copyFrom) 20 | { 21 | Checkpoints = copyFrom.Checkpoints; 22 | SpawnPoints = copyFrom.SpawnPoints; 23 | AvailableVehicles = copyFrom.AvailableVehicles; 24 | LapsAvailable = copyFrom.LapsAvailable; 25 | Trigger = copyFrom.Trigger; 26 | 27 | Name = copyFrom.Name; 28 | Description = copyFrom.Description; 29 | } 30 | } 31 | 32 | public class SpawnPoint 33 | { 34 | public Vector3 Position { get; set; } 35 | public float Heading { get; set; } 36 | } 37 | } -------------------------------------------------------------------------------- /Race/Race.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {988CD1D8-48ED-4C19-8953-79FAFDBB34DD} 8 | Library 9 | Properties 10 | Race 11 | Race 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\Server\bin\Release\GTAServer.exe 36 | 37 | 38 | False 39 | ..\libs\Lidgren.Network.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /Race/VehicleHashes.cs: -------------------------------------------------------------------------------- 1 | namespace Race 2 | { 3 | public enum VehicleHash : uint 4 | { 5 | Adder = 0xB779A091, 6 | Airbus = 0x4C80EB0E, 7 | Airtug = 0x5D0AAC8F, 8 | Akuma = 0x63ABADE7, 9 | Alpha = 0x2DB8D1AA, 10 | Ambulance = 0x45D56ADA, 11 | Annihilator = 0x31F0B376, 12 | ArmyTanker = 0xB8081009, 13 | ArmyTrailer = 0xA7FF33F5, 14 | ArmyTrailer2 = 0x9E6B14D6, 15 | Asea = 0x94204D89, 16 | Asea2 = 0x9441D8D5, 17 | Asterope = 0x8E9254FB, 18 | Bagger = 0x806B9CC3, 19 | BaleTrailer = 0xE82AE656, 20 | Baller = 0xCFCA3668, 21 | Baller2 = 0x8852855, 22 | Banshee = 0xC1E908D2, 23 | Barracks = 0xCEEA3F4B, 24 | Barracks2 = 0x4008EABB, 25 | Barracks3 = 0x2592B5CF, 26 | Bati = 0xF9300CC5, 27 | Bati2 = 0xCADD5D2D, 28 | Benson = 0x7A61B330, 29 | Besra = 0x6CBD1D6D, 30 | BfInjection = 0x432AA566, 31 | Biff = 0x32B91AE8, 32 | Bifta = 0xEB298297, 33 | Bison = 0xFEFD644F, 34 | Bison2 = 0x7B8297C5, 35 | Bison3 = 0x67B3F020, 36 | BJXL = 0x32B29A4B, 37 | Blade = 0xB820ED5E, 38 | Blazer = 0x8125BCF9, 39 | Blazer2 = 0xFD231729, 40 | Blazer3 = 0xB44F0582, 41 | Blimp = 0xF7004C86, 42 | Blimp2 = 0xDB6B4924, 43 | Blista = 0xEB70965F, 44 | Blista2 = 0x3DEE5EDA, 45 | Blista3 = 0xDCBC1C3B, 46 | Bmx = 0x43779C54, 47 | BoatTrailer = 0x1F3D44B5, 48 | BobcatXL = 0x3FC5D440, 49 | Bodhi2 = 0xAA699BB6, 50 | Boxville = 0x898ECCEA, 51 | Boxville2 = 0xF21B33BE, 52 | Boxville3 = 0x7405E08, 53 | Boxville4 = 0x1A79847A, 54 | Brawler = 0xA7CE1BC5, 55 | BType = 0x6FF6914, 56 | BType2 = 0xCE6B35A4, 57 | Buccaneer = 0xD756460C, 58 | Buccaneer2 = 0xC397F748, 59 | Buffalo = 0xEDD516C6, 60 | Buffalo2 = 0x2BEC3CBE, 61 | Buffalo3 = 0xE2C013E, 62 | Bulldozer = 0x7074F39D, 63 | Bullet = 0x9AE6DDA1, 64 | Burrito = 0xAFBB2CA4, 65 | Burrito2 = 0xC9E8FF76, 66 | Burrito3 = 0x98171BD3, 67 | Burrito4 = 0x353B561D, 68 | Burrito5 = 0x437CF2A0, 69 | Bus = 0xD577C962, 70 | Buzzard = 0x2F03547B, 71 | Buzzard2 = 0x2C75F0DD, 72 | CableCar = 0xC6C3242D, 73 | Caddy = 0x44623884, 74 | Caddy2 = 0xDFF0594C, 75 | Camper = 0x6FD95F68, 76 | Carbonizzare = 0x7B8AB45F, 77 | CarbonRS = 0xABB0C0, 78 | Cargobob = 0xFCFCB68B, 79 | Cargobob2 = 0x60A7EA10, 80 | Cargobob3 = 0x53174EEF, 81 | CargoPlane = 0x15F27762, 82 | Casco = 0x3822BDFE, 83 | Cavalcade = 0x779F23AA, 84 | Cavalcade2 = 0xD0EB2BE5, 85 | Cheetah = 0xB1D95DA0, 86 | Chino = 0x14D69010, 87 | Chino2 = 0xAED64A63, 88 | Coach = 0x84718D34, 89 | CogCabrio = 0x13B57D8A, 90 | Comet2 = 0xC1AE4D16, 91 | Coquette = 0x67BC037, 92 | Coquette2 = 0x3C4E2113, 93 | Coquette3 = 0x2EC385FE, 94 | Cruiser = 0x1ABA13B5, 95 | Crusader = 0x132D5A1A, 96 | Cuban800 = 0xD9927FE3, 97 | Cutter = 0xC3FBA120, 98 | Daemon = 0x77934CEE, 99 | Dilettante = 0xBC993509, 100 | Dilettante2 = 0x64430650, 101 | Dinghy = 0x3D961290, 102 | Dinghy2 = 0x107F392C, 103 | Dinghy3 = 0x1E5E54EA, 104 | DLoader = 0x698521E3, 105 | DockTrailer = 0x806EFBEE, 106 | Docktug = 0xCB44B1CA, 107 | Dodo = 0xCA495705, 108 | Dominator = 0x4CE68AC, 109 | Dominator2 = 0xC96B73D9, 110 | Double = 0x9C669788, 111 | Dubsta = 0x462FE277, 112 | Dubsta2 = 0xE882E5F6, 113 | Dubsta3 = 0xB6410173, 114 | Dukes = 0x2B26F456, 115 | Dukes2 = 0xEC8F7094, 116 | Dump = 0x810369E2, 117 | Dune = 0x9CF21E0F, 118 | Dune2 = 0x1FD824AF, 119 | Duster = 0x39D6779E, 120 | Elegy2 = 0xDE3D9D22, 121 | Emperor = 0xD7278283, 122 | Emperor2 = 0x8FC3AADC, 123 | Emperor3 = 0xB5FCF74E, 124 | Enduro = 0x6882FA73, 125 | EntityXF = 0xB2FE5CF9, 126 | Exemplar = 0xFFB15B5E, 127 | F620 = 0xDCBCBE48, 128 | Faction = 0x81A9CDDF, 129 | Faction2 = 0x95466BDB, 130 | Faggio2 = 0x350D1AB, 131 | FBI = 0x432EA949, 132 | FBI2 = 0x9DC66994, 133 | Felon = 0xE8A8BDA8, 134 | Felon2 = 0xFAAD85EE, 135 | Feltzer2 = 0x8911B9F5, 136 | Feltzer3 = 0xA29D6D10, 137 | FireTruck = 0x73920F8E, 138 | Fixter = 0xCE23D3BF, 139 | Flatbed = 0x50B0215A, 140 | Forklift = 0x58E49664, 141 | Fq2 = 0xBC32A33B, 142 | Freight = 0x3D6AAA9B, 143 | FreightCar = 0x0AFD22A6, 144 | FreightCont1 = 0x36DCFF98, 145 | FreightCont2 = 0x0E512E79, 146 | FreightGrain = 0x264D9262, 147 | FreightTrailer = 0xD1ABB666, 148 | Frogger = 0x2C634FBD, 149 | Frogger2 = 0x742E9AC0, 150 | Fugitive = 0x71CB2FFB, 151 | Furoregt = 0xBF1691E0, 152 | Fusilade = 0x1DC0BA53, 153 | Futo = 0x7836CE2F, 154 | Gauntlet = 0x94B395C5, 155 | Gauntlet2 = 0x14D22159, 156 | GBurrito = 0x97FA4F36, 157 | GBurrito2 = 0x11AA0E14, 158 | Glendale = 0x47A6BC1, 159 | GrainTrailer = 0x3CC7F596, 160 | Granger = 0x9628879C, 161 | Gresley = 0xA3FC0F4D, 162 | Guardian = 0x825A9F4C, 163 | Habanero = 0x34B7390F, 164 | Hakuchou = 0x4B6C568A, 165 | Handler = 0x1A7FCEFA, 166 | Hauler = 0x5A82F9AE, 167 | Hexer = 0x11F76C14, 168 | Hotknife = 0x239E390, 169 | Huntley = 0x1D06D681, 170 | Hydra = 0x39D6E83F, 171 | Infernus = 0x18F25AC7, 172 | Ingot = 0xB3206692, 173 | Innovation = 0xF683EACA, 174 | Insurgent = 0x9114EADA, 175 | Insurgent2 = 0x7B7E56F0, 176 | Intruder = 0x34DD8AA1, 177 | Issi2 = 0xB9CB3B69, 178 | Jackal = 0xDAC67112, 179 | JB700 = 0x3EAB5555, 180 | Jester = 0xB2A716A3, 181 | Jester2 = 0xBE0E6126, 182 | Jet = 0x3F119114, 183 | Jetmax = 0x33581161, 184 | Journey = 0xF8D48E7A, 185 | Kalahari = 0x5852838, 186 | Khamelion = 0x206D1B68, 187 | Kuruma = 0xAE2BFE94, 188 | Kuruma2 = 0x187D938D, 189 | Landstalker = 0x4BA4E8DC, 190 | Lazer = 0xB39B0AE6, 191 | Lectro = 0x26321E67, 192 | Lguard = 0x1BF8D381, 193 | Lurcher = 0x7B47A6A7, 194 | Luxor = 0x250B0C5E, 195 | Luxor2 = 0xB79F589E, 196 | Mammatus = 0x97E55D11, 197 | Manana = 0x81634188, 198 | Marquis = 0xC1CE1183, 199 | Marshall = 0x49863E9C, 200 | Massacro = 0xF77ADE32, 201 | Massacro2 = 0xDA5819A3, 202 | Maverick = 0x9D0450CA, 203 | Mesa = 0x36848602, 204 | Mesa2 = 0xD36A4B44, 205 | Mesa3 = 0x84F42E51, 206 | Miljet = 0x9D80F93, 207 | Minivan = 0xED7EADA4, 208 | Mixer = 0xD138A6BB, 209 | Mixer2 = 0x1C534995, 210 | Monroe = 0xE62B361B, 211 | Monster = 0xCD93A7DB, 212 | Moonbeam = 0x1F52A43F, 213 | Moonbeam2 = 0x710A2B9B, 214 | Mower = 0x6A4BD8F6, 215 | Mule = 0x35ED670B, 216 | Mule2 = 0xC1632BEB, 217 | Mule3 = 0x85A5B471, 218 | Nemesis = 0xDA288376, 219 | Ninef = 0x3D8FA25C, 220 | Ninef2 = 0xA8E38B01, 221 | Oracle = 0x506434F6, 222 | Oracle2 = 0xE18195B2, 223 | Osiris = 0x767164D6, 224 | Packer = 0x21EEE87D, 225 | Panto = 0xE644E480, 226 | Paradise = 0x58B3979C, 227 | Patriot = 0xCFCFEB3B, 228 | PBus = 0x885F3671, 229 | PCJ = 0xC9CEAF06, 230 | Penumbra = 0xE9805550, 231 | Peyote = 0x6D19CCBC, 232 | Phantom = 0x809AA4CB, 233 | Phoenix = 0x831A21D5, 234 | Picador = 0x59E0FBF3, 235 | Pigalle = 0x404B6381, 236 | Police = 0x79FBB0C5, 237 | Police2 = 0x9F05F101, 238 | Police3 = 0x71FA16EA, 239 | Police4 = 0x8A63C7B9, 240 | Policeb = 0xFDEFAEC3, 241 | PoliceOld1 = 0xA46462F7, 242 | PoliceOld2 = 0x95F4C618, 243 | PoliceT = 0x1B38E955, 244 | Polmav = 0x1517D4D9, 245 | Pony = 0xF8DE29A8, 246 | Pony2 = 0x38408341, 247 | Pounder = 0x7DE35E7D, 248 | Prairie = 0xA988D3A2, 249 | Pranger = 0x2C33B46E, 250 | Predator = 0xE2E7D4AB, 251 | Premier = 0x8FB66F9B, 252 | Primo = 0xBB6B404F, 253 | Primo2 = 0x86618EDA, 254 | PropTrailer = 0x153E1B0A, 255 | Radi = 0x9D96B45B, 256 | RakeTrailer = 0x174CB172, 257 | RancherXL = 0x6210CBB0, 258 | RancherXL2 = 0x7341576B, 259 | RapidGT = 0x8CB29A14, 260 | RapidGT2 = 0x679450AF, 261 | RatLoader = 0xD83C13CE, 262 | RatLoader2 = 0xDCE1D9F7, 263 | Rebel = 0xB802DD46, 264 | Rebel2 = 0x8612B64B, 265 | Regina = 0xFF22D208, 266 | RentalBus = 0xBE819C63, 267 | Rhapsody = 0x322CF98F, 268 | Rhino = 0x2EA68690, 269 | Riot = 0xB822A1AA, 270 | Ripley = 0xCD935EF9, 271 | Rocoto = 0x7F5C91F1, 272 | Romero = 0x2560B2FC, 273 | Rubble = 0x9A5B1DCC, 274 | Ruffian = 0xCABD11E8, 275 | Ruiner = 0xF26CEFF9, 276 | Rumpo = 0x4543B74D, 277 | Rumpo2 = 0x961AFEF7, 278 | SabreGT = 0x9B909C94, 279 | Sadler = 0xDC434E51, 280 | Sadler2 = 0x2BC345D1, 281 | Sanchez = 0x2EF89E46, 282 | Sanchez2 = 0xA960B13E, 283 | Sandking = 0xB9210FD0, 284 | Sandking2 = 0x3AF8C345, 285 | Savage = 0xFB133A17, 286 | Schafter2 = 0xB52B5113, 287 | Schwarzer = 0xD37B7976, 288 | Scorcher = 0xF4E1AA15, 289 | Scrap = 0x9A9FD3DF, 290 | Seashark = 0xC2974024, 291 | Seashark2 = 0xDB4388E4, 292 | Seminole = 0x48CECED3, 293 | Sentinel = 0x50732C82, 294 | Sentinel2 = 0x3412AE2D, 295 | Serrano = 0x4FB1A214, 296 | Shamal = 0xB79C1BF5, 297 | Sheriff = 0x9BAA707C, 298 | Sheriff2 = 0x72935408, 299 | Skylift = 0x3E48BF23, 300 | SlamVan = 0x2B7F9DE3, 301 | SlamVan2 = 0x31ADBBFC, 302 | Sovereign = 0x2C509634, 303 | Speeder = 0xDC60D2B, 304 | Speedo = 0xCFB3870C, 305 | Speedo2 = 0x2B6DC64A, 306 | Squalo = 0x17DF5EC2, 307 | Stalion = 0x72A4C31E, 308 | Stalion2 = 0xE80F67EE, 309 | Stanier = 0xA7EDE74D, 310 | Stinger = 0x5C23AF9B, 311 | StingerGT = 0x82E499FA, 312 | Stockade = 0x6827CF72, 313 | Stockade3 = 0xF337AB36, 314 | Stratum = 0x66B4FC45, 315 | Stretch = 0x8B13F083, 316 | Stunt = 0x81794C70, 317 | Submersible = 0x2DFF622F, 318 | Submersible2 = 0xC07107EE, 319 | Sultan = 0x39DA2754, 320 | Suntrap = 0xEF2295C9, 321 | Superd = 0x42F2ED16, 322 | Surano = 0x16E478C1, 323 | Surfer = 0x29B0DA97, 324 | Surfer2 = 0xB1D80E06, 325 | Surge = 0x8F0E3594, 326 | Swift2 = 0x4019CB4C, 327 | Swift = 0xEBC24DF2, 328 | T20 = 0x6322B39A, 329 | Taco = 0x744CA80D, 330 | Tailgater = 0xC3DDFDCE, 331 | Tanker = 0xD46F4737, 332 | Tanker2 = 0x74998082, 333 | TankerCar = 0x22EDDC30, 334 | Taxi = 0xC703DB5F, 335 | Technical = 0x83051506, 336 | Thrust = 0x6D6F8F43, 337 | TipTruck = 0x2E19879, 338 | TipTruck2 = 0xC7824E5E, 339 | Titan = 0x761E2AD3, 340 | Tornado = 0x1BB290BC, 341 | Tornado2 = 0x5B42A5C4, 342 | Tornado3 = 0x690A4153, 343 | Tornado4 = 0x86CF7CDD, 344 | Toro = 0x3FD5AA2F, 345 | Tourbus = 0x73B1C3CB, 346 | TowTruck = 0xB12314E0, 347 | TowTruck2 = 0xE5A2D6C6, 348 | TR2 = 0x7BE032C6, 349 | TR3 = 0x6A59902D, 350 | TR4 = 0x7CAB34D0, 351 | Tractor = 0x61D6BA8C, 352 | Tractor2 = 0x843B73DE, 353 | Tractor3 = 0x562A97BD, 354 | TrailerLogs = 0x782A236D, 355 | Trailers = 0xCBB2BE0E, 356 | Trailers2 = 0xA1DA3C91, 357 | Trailers3 = 0x8548036D, 358 | TrailerSmall = 0x2A72BEAB, 359 | Trash = 0x72435A19, 360 | Trash2 = 0xB527915C, 361 | TRFlat = 0xAF62F6B2, 362 | TriBike = 0x4339CD69, 363 | TriBike2 = 0xB67597EC, 364 | TriBike3 = 0xE823FB48, 365 | Tropic = 0x1149422F, 366 | Turismor = 0x185484E1, 367 | TVTrailer = 0x967620BE, 368 | UtilityTruck = 0x1ED0A534, 369 | UtilityTruck2 = 0x34E6BF6B, 370 | UtilityTruck3 = 0x7F2153DF, 371 | UtilliTruck = 0x1ED0A534, 372 | UtilliTruck2 = 0x34E6BF6B, 373 | UtilliTruck3 = 0x7F2153DF, 374 | Vacca = 0x142E0DC3, 375 | Vader = 0xF79A00F7, 376 | Valkyrie = 0xA09E15FD, 377 | Velum = 0x9C429B6A, 378 | Velum2 = 0x403820E8, 379 | Vestra = 0x4FF77E37, 380 | Vigero = 0xCEC6B9B7, 381 | Vindicator = 0xAF599F01, 382 | Virgo = 0xE2504942, 383 | Voltic = 0x9F4B77BE, 384 | Voodoo = 0x779B4F2D, 385 | Voodoo2 = 0x1F3766E3, 386 | Warrener = 0x51D83328, 387 | Washington = 0x69F06B57, 388 | Windsor = 0x5E4327C8, 389 | Youga = 0x3E5F6B8, 390 | Zentorno = 0xAC5DF515, 391 | Zion = 0xBD1B39C3, 392 | Zion2 = 0xB8E2AE18, 393 | Ztype = 0x2D3BD401, 394 | }; 395 | } -------------------------------------------------------------------------------- /Server/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Server/ChatData.cs: -------------------------------------------------------------------------------- 1 | using ProtoBuf; 2 | 3 | namespace GTAServer 4 | { 5 | [ProtoContract] 6 | public class ChatData 7 | { 8 | [ProtoMember(1)] 9 | public long Id { get; set; } 10 | [ProtoMember(2)] 11 | public string Sender { get; set; } 12 | [ProtoMember(3)] 13 | public string Message { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Server/GTAServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {559EE224-BF7B-49D8-9CEE-11E6BA71FE4E} 8 | Exe 9 | Properties 10 | GTAServer 11 | GTAServer 12 | v4.5.1 13 | 512 14 | 15 | publish\ 16 | true 17 | Disk 18 | false 19 | Foreground 20 | 7 21 | Days 22 | false 23 | false 24 | true 25 | 0 26 | 1.0.0.%2a 27 | false 28 | false 29 | true 30 | 31 | 32 | AnyCPU 33 | true 34 | full 35 | false 36 | bin\Debug\ 37 | DEBUG;TRACE 38 | prompt 39 | 4 40 | false 41 | 42 | 43 | AnyCPU 44 | pdbonly 45 | true 46 | bin\Release\ 47 | TRACE;__CONSTRAINED__ 48 | prompt 49 | 4 50 | false 51 | 52 | 53 | 54 | 55 | 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ..\libs\Lidgren.Network.dll 65 | 66 | 67 | ..\libs\protobuf-net.dll 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | False 95 | Microsoft .NET Framework 4.5.2 %28x86 and x64%29 96 | true 97 | 98 | 99 | False 100 | .NET Framework 3.5 SP1 101 | false 102 | 103 | 104 | 105 | 112 | -------------------------------------------------------------------------------- /Server/NativeData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using ProtoBuf; 4 | 5 | namespace GTAServer 6 | { 7 | [ProtoContract] 8 | public class NativeResponse 9 | { 10 | [ProtoMember(1)] 11 | public NativeArgument Response { get; set; } 12 | 13 | [ProtoMember(2)] 14 | public string Id { get; set; } 15 | } 16 | 17 | [ProtoContract] 18 | public class NativeTickCall 19 | { 20 | [ProtoMember(1)] 21 | public NativeData Native { get; set; } 22 | 23 | [ProtoMember(2)] 24 | public string Identifier { get; set; } 25 | } 26 | 27 | [ProtoContract] 28 | public class NativeData 29 | { 30 | [ProtoMember(1)] 31 | public ulong Hash { get; set; } 32 | 33 | [ProtoMember(2)] 34 | public List Arguments { get; set; } 35 | 36 | [ProtoMember(3)] 37 | public NativeArgument ReturnType { get; set; } 38 | 39 | [ProtoMember(4)] 40 | public string Id { get; set; } 41 | } 42 | 43 | [ProtoContract] 44 | [ProtoInclude(2, typeof(IntArgument))] 45 | [ProtoInclude(3, typeof(UIntArgument))] 46 | [ProtoInclude(4, typeof(StringArgument))] 47 | [ProtoInclude(5, typeof(FloatArgument))] 48 | [ProtoInclude(6, typeof(BooleanArgument))] 49 | [ProtoInclude(7, typeof(LocalPlayerArgument))] 50 | [ProtoInclude(8, typeof(Vector3Argument))] 51 | [ProtoInclude(9, typeof(LocalGamePlayerArgument))] 52 | public class NativeArgument 53 | { 54 | [ProtoMember(1)] 55 | public string Id { get; set; } 56 | } 57 | 58 | [ProtoContract] 59 | public class LocalPlayerArgument : NativeArgument 60 | { 61 | } 62 | 63 | [ProtoContract] 64 | public class LocalGamePlayerArgument : NativeArgument 65 | { 66 | } 67 | 68 | [ProtoContract] 69 | public class OpponentPedHandleArgument : NativeArgument 70 | { 71 | public OpponentPedHandleArgument(long opponentHandle) 72 | { 73 | Data = opponentHandle; 74 | } 75 | 76 | [ProtoMember(1)] 77 | public long Data { get; set; } 78 | } 79 | 80 | [ProtoContract] 81 | public class IntArgument : NativeArgument 82 | { 83 | [ProtoMember(1)] 84 | public int Data { get; set; } 85 | } 86 | 87 | [ProtoContract] 88 | public class UIntArgument : NativeArgument 89 | { 90 | [ProtoMember(1)] 91 | public uint Data { get; set; } 92 | } 93 | 94 | [ProtoContract] 95 | public class StringArgument : NativeArgument 96 | { 97 | [ProtoMember(1)] 98 | public string Data { get; set; } 99 | } 100 | 101 | [ProtoContract] 102 | public class FloatArgument : NativeArgument 103 | { 104 | [ProtoMember(1)] 105 | public float Data { get; set; } 106 | } 107 | 108 | [ProtoContract] 109 | public class BooleanArgument : NativeArgument 110 | { 111 | [ProtoMember(1)] 112 | public bool Data { get; set; } 113 | } 114 | 115 | [ProtoContract] 116 | public class Vector3Argument : NativeArgument 117 | { 118 | [ProtoMember(1)] 119 | public float X { get; set; } 120 | [ProtoMember(2)] 121 | public float Y { get; set; } 122 | [ProtoMember(3)] 123 | public float Z { get; set; } 124 | } 125 | } -------------------------------------------------------------------------------- /Server/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Xml.Serialization; 9 | 10 | namespace GTAServer 11 | { 12 | public static class Program 13 | { 14 | public static string Location { get { return AppDomain.CurrentDomain.BaseDirectory; } } 15 | public static GameServer ServerInstance { get; set; } 16 | 17 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 18 | [return: MarshalAs(UnmanagedType.Bool)] 19 | public static extern bool DeleteFile(string name); 20 | 21 | static void Main(string[] args) 22 | { 23 | var settings = ReadSettings(Program.Location + "Settings.xml"); 24 | 25 | Console.WriteLine("Name: " + settings.Name); 26 | Console.WriteLine("Port: " + settings.Port); 27 | Console.WriteLine("Player Limit: " + settings.MaxPlayers); 28 | Console.WriteLine("Starting..."); 29 | 30 | ServerInstance = new GameServer(settings.Port, settings.Name, settings.Gamemode); 31 | ServerInstance.PasswordProtected = settings.PasswordProtected; 32 | ServerInstance.Password = settings.Password; 33 | ServerInstance.AnnounceSelf = settings.Announce; 34 | ServerInstance.MasterServer = settings.MasterServer; 35 | ServerInstance.MaxPlayers = settings.MaxPlayers; 36 | ServerInstance.AllowDisplayNames = settings.AllowDisplayNames; 37 | 38 | ServerInstance.Start(settings.Filterscripts); 39 | 40 | Console.WriteLine("Started! Waiting for connections."); 41 | 42 | while (true) 43 | { 44 | ServerInstance.Tick(); 45 | System.Threading.Thread.Sleep(10); // Reducing CPU Usage (Win7 from average 15 % to 0-1 %, Linux from 100 % to 0-2 %) 46 | } 47 | } 48 | 49 | static ServerSettings ReadSettings(string path) 50 | { 51 | var ser = new XmlSerializer(typeof(ServerSettings)); 52 | 53 | ServerSettings settings = null; 54 | 55 | if (File.Exists(path)) 56 | { 57 | using (var stream = File.OpenRead(path)) settings = (ServerSettings)ser.Deserialize(stream); 58 | 59 | using (var stream = new FileStream(path, File.Exists(path) ? FileMode.Truncate : FileMode.Create, FileAccess.ReadWrite)) ser.Serialize(stream, settings); 60 | } 61 | else 62 | { 63 | using (var stream = File.OpenWrite(path)) ser.Serialize(stream, settings = new ServerSettings()); 64 | } 65 | 66 | return settings; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("GTAServer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("GTAServer")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("559ee224-bf7b-49d8-9cee-11e6ba71fe4e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Server/ServerScript.cs: -------------------------------------------------------------------------------- 1 | using Lidgren.Network; 2 | 3 | namespace GTAServer 4 | { 5 | public class ServerScript 6 | { 7 | public virtual string Name { get; set; } 8 | 9 | public virtual void Start() 10 | { 11 | } 12 | 13 | 14 | public virtual bool OnChatMessage(Client sender, string message) 15 | { 16 | return true; 17 | } 18 | 19 | public virtual bool OnPlayerConnect(Client player) 20 | { 21 | return true; 22 | } 23 | 24 | public virtual void OnIncomingConnection(Client player) 25 | { 26 | } 27 | 28 | public virtual bool OnPlayerDisconnect(Client player) 29 | { 30 | return true; 31 | } 32 | 33 | 34 | public virtual void OnConnectionRefused(Client player, string reason) 35 | { 36 | } 37 | 38 | public virtual void OnPlayerKilled(Client player) 39 | { 40 | } 41 | 42 | public virtual void OnTick() 43 | { 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Server/ServerSettings.cs: -------------------------------------------------------------------------------- 1 | namespace GTAServer 2 | { 3 | public class ServerSettings 4 | { 5 | public string Name { get; set; } 6 | public int MaxPlayers { get; set; } 7 | public int Port { get; set; } 8 | public bool PasswordProtected { get; set; } 9 | public string Password { get; set; } 10 | public bool Announce { get; set; } 11 | public string MasterServer { get; set; } 12 | 13 | public bool AllowDisplayNames { get; set; } 14 | 15 | public string Gamemode { get; set; } 16 | public string[] Filterscripts { get; set; } 17 | 18 | public ServerSettings() 19 | { 20 | Port = 4499; 21 | MaxPlayers = 16; 22 | Name = "Simple GTA Server"; 23 | Password = "changeme"; 24 | PasswordProtected = false; 25 | Gamemode = "freeroam"; 26 | Announce = true; 27 | AllowDisplayNames = true; 28 | MasterServer = "http://46.101.1.92/"; 29 | Filterscripts = new string[] { "" }; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Server/VehicleData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using ProtoBuf; 4 | 5 | namespace GTAServer 6 | { 7 | public enum PacketType 8 | { 9 | VehiclePositionData = 0, 10 | ChatData = 1, 11 | PlayerDisconnect = 2, 12 | PedPositionData = 3, 13 | NpcVehPositionData = 4, 14 | NpcPedPositionData = 5, 15 | WorldSharingStop = 6, 16 | DiscoveryResponse = 7, 17 | ConnectionRequest = 8, 18 | NativeCall = 9, 19 | NativeResponse = 10, 20 | PlayerKilled = 11, 21 | NativeTick = 12, 22 | NativeTickRecall = 13, 23 | NativeOnDisconnect = 14, 24 | NativeOnDisconnectRecall = 15, 25 | } 26 | 27 | public enum ScriptVersion 28 | { 29 | Unknown = 0, 30 | VERSION_0_6 = 1, 31 | VERSION_0_6_1 = 2, 32 | VERSION_0_7 = 3, 33 | VERSION_0_8_1 = 4, 34 | VERSION_0_9 = 5, 35 | } 36 | 37 | [ProtoContract] 38 | public class DiscoveryResponse 39 | { 40 | [ProtoMember(1)] 41 | public string ServerName { get; set; } 42 | [ProtoMember(2)] 43 | public int MaxPlayers { get; set; } 44 | [ProtoMember(3)] 45 | public int PlayerCount { get; set; } 46 | [ProtoMember(4)] 47 | public bool PasswordProtected { get; set; } 48 | [ProtoMember(5)] 49 | public int Port { get; set; } 50 | [ProtoMember(6)] 51 | public string Gamemode { get; set; } 52 | } 53 | 54 | [ProtoContract] 55 | public class ConnectionRequest 56 | { 57 | [ProtoMember(1)] 58 | public string Name { get; set; } 59 | 60 | [ProtoMember(2)] 61 | public string Password { get; set; } 62 | 63 | [ProtoMember(3)] 64 | public string DisplayName { get; set; } 65 | 66 | [ProtoMember(4)] 67 | public int GameVersion { get; set; } 68 | 69 | [ProtoMember(5)] 70 | public byte ScriptVersion { get; set; } 71 | } 72 | 73 | [ProtoContract] 74 | public class PlayerDisconnect 75 | { 76 | [ProtoMember(1)] 77 | public long Id { get; set; } 78 | } 79 | 80 | [ProtoContract] 81 | public class VehicleData 82 | { 83 | [ProtoMember(1)] 84 | public long Id { get; set; } 85 | [ProtoMember(2)] 86 | public string Name { get; set; } 87 | 88 | [ProtoMember(3)] 89 | public int VehicleModelHash { get; set; } 90 | [ProtoMember(4)] 91 | public int PedModelHash { get; set; } 92 | [ProtoMember(5)] 93 | public int PrimaryColor { get; set; } 94 | [ProtoMember(6)] 95 | public int SecondaryColor { get; set; } 96 | 97 | [ProtoMember(7)] 98 | public Vector3 Position { get; set; } 99 | [ProtoMember(8)] 100 | public Quaternion Quaternion { get; set; } 101 | 102 | [ProtoMember(9)] 103 | public int VehicleSeat { get; set; } 104 | 105 | [ProtoMember(10)] 106 | public int VehicleHealth { get; set; } 107 | 108 | [ProtoMember(11)] 109 | public int PlayerHealth { get; set; } 110 | 111 | [ProtoMember(12)] 112 | public float Latency { get; set; } 113 | 114 | [ProtoMember(13)] 115 | public Dictionary VehicleMods { get; set; } 116 | 117 | [ProtoMember(14)] 118 | public bool IsPressingHorn { get; set; } 119 | 120 | [ProtoMember(15)] 121 | public bool IsSirenActive { get; set; } 122 | 123 | [ProtoMember(16)] 124 | public float Speed { get; set; } 125 | } 126 | 127 | [ProtoContract] 128 | public class PedData 129 | { 130 | [ProtoMember(1)] 131 | public long Id { get; set; } 132 | [ProtoMember(2)] 133 | public string Name { get; set; } 134 | 135 | [ProtoMember(3)] 136 | public int PedModelHash { get; set; } 137 | 138 | [ProtoMember(4)] 139 | public Vector3 Position { get; set; } 140 | [ProtoMember(5)] 141 | public Quaternion Quaternion { get; set; } 142 | 143 | [ProtoMember(6)] 144 | public bool IsJumping { get; set; } 145 | [ProtoMember(7)] 146 | public bool IsShooting { get; set; } 147 | [ProtoMember(8)] 148 | public bool IsAiming { get; set; } 149 | [ProtoMember(9)] 150 | public Vector3 AimCoords { get; set; } 151 | [ProtoMember(10)] 152 | public int WeaponHash { get; set; } 153 | 154 | [ProtoMember(11)] 155 | public int PlayerHealth { get; set; } 156 | 157 | [ProtoMember(12)] 158 | public float Latency { get; set; } 159 | 160 | [ProtoMember(13)] 161 | public Dictionary PedProps { get; set; } 162 | 163 | [ProtoMember(14)] 164 | public bool IsParachuteOpen { get; set; } 165 | } 166 | 167 | 168 | [ProtoContract] 169 | public class Vector3 170 | { 171 | public Vector3() 172 | { 173 | X = 0f; 174 | Y = 0f; 175 | Z = 0f; 176 | } 177 | 178 | public Vector3(float x, float y, float z) 179 | { 180 | X = x; 181 | Y = y; 182 | Z = z; 183 | } 184 | 185 | [ProtoMember(1)] 186 | public float X { get; set; } 187 | [ProtoMember(2)] 188 | public float Y { get; set; } 189 | [ProtoMember(3)] 190 | public float Z { get; set; } 191 | } 192 | 193 | [ProtoContract] 194 | public class Quaternion 195 | { 196 | [ProtoMember(1)] 197 | public float X { get; set; } 198 | [ProtoMember(2)] 199 | public float Y { get; set; } 200 | [ProtoMember(3)] 201 | public float Z { get; set; } 202 | [ProtoMember(4)] 203 | public float W { get; set; } 204 | } 205 | } -------------------------------------------------------------------------------- /Server/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /gtamasterserver/.gitignore: -------------------------------------------------------------------------------- 1 | *.ini 2 | *.pyc -------------------------------------------------------------------------------- /gtamasterserver/Procfile: -------------------------------------------------------------------------------- 1 | web: python app.py -------------------------------------------------------------------------------- /gtamasterserver/app.py: -------------------------------------------------------------------------------- 1 | import flask 2 | import threading 3 | from datetime import datetime 4 | from json import dumps 5 | from os import environ 6 | from waitress import serve 7 | from time import sleep 8 | 9 | app = flask.Flask(__name__) 10 | 11 | servers = {} 12 | 13 | @app.route('/', methods=['GET', 'POST']) 14 | def index(): 15 | global servers 16 | if flask.request.method == 'POST': 17 | dejson = {'port': flask.request.data} 18 | print dejson['port'] 19 | srvString = flask.request.remote_addr + ':' + dejson['port'] 20 | servers[srvString] = datetime.now() 21 | return '200' 22 | else: 23 | return dumps({"list":servers.keys()}) 24 | 25 | 26 | def checkThread(): 27 | print 'cleaning list...' 28 | for server in dict(servers): 29 | date = servers[server] 30 | if (datetime.now() - date).total_seconds() > 10*60: 31 | del servers[server] 32 | 33 | sleep(10*60) 34 | checkThread() 35 | 36 | 37 | if __name__ == '__main__': 38 | t = threading.Thread(target=checkThread) 39 | t.daemon = True 40 | t.start() 41 | 42 | app.debug = True #InDev ONLY 43 | #serve(app, port=int(environ['PORT'])) #For deployment 44 | app.run() #Run our app. #InDev ONLY -------------------------------------------------------------------------------- /gtamasterserver/json_test.py: -------------------------------------------------------------------------------- 1 | import json 2 | import requests 3 | 4 | resp = requests.post('http://localhost:5000/', data='4499') 5 | print resp -------------------------------------------------------------------------------- /gtamasterserver/ping_test.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | UDP_IP = "127.0.0.1" 4 | UDP_PORT = 4499 5 | MESSAGE = "ping" 6 | 7 | 8 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 9 | 10 | sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) -------------------------------------------------------------------------------- /gtamasterserver/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | waitress -------------------------------------------------------------------------------- /libs/Lidgren.Network.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guad/GTACoop/1e964af528dcab5e028802a6c70992b2d453fcc0/libs/Lidgren.Network.dll -------------------------------------------------------------------------------- /libs/NativeUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guad/GTACoop/1e964af528dcab5e028802a6c70992b2d453fcc0/libs/NativeUI.dll -------------------------------------------------------------------------------- /libs/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guad/GTACoop/1e964af528dcab5e028802a6c70992b2d453fcc0/libs/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /libs/ScriptHookVDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guad/GTACoop/1e964af528dcab5e028802a6c70992b2d453fcc0/libs/ScriptHookVDotNet.dll -------------------------------------------------------------------------------- /libs/protobuf-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guad/GTACoop/1e964af528dcab5e028802a6c70992b2d453fcc0/libs/protobuf-net.dll --------------------------------------------------------------------------------