├── .gitignore ├── .travis.yml ├── .vs └── SAMPLauncherNET │ └── v15 │ └── .suo ├── FEATURES.md ├── LICENCE.md ├── README.md ├── SAMPLauncherNET.sln ├── SAMPLauncherNET ├── Images │ ├── delete_icon.png │ ├── edit_icon.png │ ├── github_icon.png │ ├── github_large_icon.png │ ├── install_icon.png │ ├── new_icon.png │ ├── open_folder_icon.png │ ├── patch_icon.png │ ├── samp-hd.png │ ├── samp-inactive.png │ ├── samp.png │ ├── samp_logo.png │ └── view_icon.png ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── SAMPLauncherNET.csproj ├── SAMPLauncherNET.csproj.user ├── Source │ └── SAMPLauncherNET │ │ ├── Core │ │ ├── APIDataContract.cs │ │ ├── ChatlogFormatter.cs │ │ ├── DeveloperToolsConfigDataContract.cs │ │ ├── EChatlogFormatType.cs │ │ ├── EPluginProvider.cs │ │ ├── ERequestResponseType.cs │ │ ├── EServerListType.cs │ │ ├── EUpdateFrequency.cs │ │ ├── FavouriteDataContract.cs │ │ ├── FavouriteServer.cs │ │ ├── FileResource.cs │ │ ├── FileState.cs │ │ ├── FilterOption.cs │ │ ├── FreeGeoIPDataContract.cs │ │ ├── GeoLocationData.cs │ │ ├── GeoLocationProvider.cs │ │ ├── GeoLocator.cs │ │ ├── IndexedServerListConnector.cs │ │ ├── InstalledPlugin.cs │ │ ├── Kernel32.cs │ │ ├── LauncherConfigDataContract.cs │ │ ├── MediaState.cs │ │ ├── OnFilterEventHandler.cs │ │ ├── PingString.cs │ │ ├── Player.cs │ │ ├── PlayerCountString.cs │ │ ├── PluginDataContract.cs │ │ ├── PluginProvider.cs │ │ ├── Program.cs │ │ ├── RequestsRequired.cs │ │ ├── SAMP.cs │ │ ├── SAMPCTLProvider.cs │ │ ├── SAMPConfig.cs │ │ ├── SAMPProvider.cs │ │ ├── SAMPServersAPIServer.cs │ │ ├── SAMPServersAPIServerDataContract.cs │ │ ├── SAMPVersionDataContract.cs │ │ ├── Server.cs │ │ ├── ServerListConnector.cs │ │ ├── ServerListEntry.cs │ │ ├── ServerResponseDelegate.cs │ │ ├── Session.cs │ │ ├── SessionDataContract.cs │ │ ├── SessionProvider.cs │ │ ├── SessionsCache.cs │ │ ├── TaskbarProgress.cs │ │ ├── ThumbnailsCache.cs │ │ ├── Utils.cs │ │ └── WebClientEx.cs │ │ └── UI │ │ ├── Controls │ │ ├── FilterUserControl.Designer.cs │ │ ├── FilterUserControl.cs │ │ ├── FilterUserControl.resx │ │ ├── SessionServerUserControl.Designer.cs │ │ ├── SessionServerUserControl.cs │ │ ├── SessionServerUserControl.resx │ │ ├── SessionUserControl.Designer.cs │ │ ├── SessionUserControl.cs │ │ └── SessionUserControl.resx │ │ └── Forms │ │ ├── APIForm.Designer.cs │ │ ├── APIForm.cs │ │ ├── APIForm.resx │ │ ├── AddAddressToFavouriteListForm.Designer.cs │ │ ├── AddAddressToFavouriteListForm.cs │ │ ├── AddAddressToFavouriteListForm.resx │ │ ├── ConnectForm.Designer.cs │ │ ├── ConnectForm.cs │ │ ├── ConnectForm.resx │ │ ├── ConnectHostForm.Designer.cs │ │ ├── ConnectHostForm.cs │ │ ├── ConnectHostForm.resx │ │ ├── DeveloperToolsConfigForm.Designer.cs │ │ ├── DeveloperToolsConfigForm.cs │ │ ├── DeveloperToolsConfigForm.resx │ │ ├── DownloadProgressForm.Designer.cs │ │ ├── DownloadProgressForm.cs │ │ ├── DownloadProgressForm.resx │ │ ├── ExtendedServerInformationForm.Designer.cs │ │ ├── ExtendedServerInformationForm.cs │ │ ├── ExtendedServerInformationForm.resx │ │ ├── FavouriteListsForm.Designer.cs │ │ ├── FavouriteListsForm.cs │ │ ├── FavouriteListsForm.resx │ │ ├── LoadingForm.Designer.cs │ │ ├── LoadingForm.cs │ │ ├── LoadingForm.resx │ │ ├── MainForm.Designer.cs │ │ ├── MainForm.cs │ │ ├── MainForm.resx │ │ ├── PluginDataForm.Designer.cs │ │ ├── PluginDataForm.cs │ │ ├── PluginDataForm.resx │ │ ├── RCONPasswordForm.Designer.cs │ │ ├── RCONPasswordForm.cs │ │ ├── RCONPasswordForm.resx │ │ ├── SessionForm.Designer.cs │ │ ├── SessionForm.cs │ │ ├── SessionForm.resx │ │ ├── UpdateNotificationForm.Designer.cs │ │ ├── UpdateNotificationForm.cs │ │ └── UpdateNotificationForm.resx ├── languages │ ├── de-DE.json │ ├── en-GB.json │ ├── es-419.json │ ├── ge-GE.json │ ├── nl-BE.json │ ├── pt-BR.json │ ├── pt-PT.json │ ├── ru-RU.json │ └── uk-UA.json ├── libs │ ├── INIEngine.dll │ ├── MaterialSkin.dll │ ├── Ude.dll │ └── WinFormsTranslator.dll ├── obj │ └── Debug │ │ ├── CoreCompileInputs.cache │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── TempPE │ │ ├── Languages.de-DE.Designer.cs.dll │ │ ├── Languages.en-GB.Designer.cs.dll │ │ └── Properties.Resources.Designer.cs.dll │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs ├── packages.config └── samp.ico ├── api.json ├── libs ├── MaterialSkin.dll └── UpdaterNET.dll ├── plugins.json ├── screenshots ├── screenshot001.png ├── screenshot002.png ├── screenshot003.png ├── screenshot004.png ├── screenshot005.png ├── screenshot006.png ├── screenshot007.png ├── screenshot008.png ├── screenshot009.png ├── screenshot010.png ├── screenshot011.png ├── screenshot012.png ├── screenshot013.png ├── screenshot014.png ├── screenshot015.png ├── screenshot016.png ├── screenshot017.png ├── screenshot018.png └── screenshot019.png ├── update.json └── versions.json /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # Benchmark Results 46 | BenchmarkDotNet.Artifacts/ 47 | 48 | # .NET Core 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | **/Properties/launchSettings.json 53 | 54 | *_i.c 55 | *_p.c 56 | *_i.h 57 | *.ilk 58 | *.meta 59 | *.obj 60 | *.pch 61 | *.pdb 62 | *.pgc 63 | *.pgd 64 | *.rsp 65 | *.sbr 66 | *.tlb 67 | *.tli 68 | *.tlh 69 | *.tmp 70 | *.tmp_proj 71 | *.log 72 | *.vspscc 73 | *.vssscc 74 | .builds 75 | *.pidb 76 | *.svclog 77 | *.scc 78 | 79 | # Chutzpah Test files 80 | _Chutzpah* 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opendb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | *.VC.db 91 | *.VC.VC.opendb 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | *.sap 98 | 99 | # TFS 2012 Local Workspace 100 | $tf/ 101 | 102 | # Guidance Automation Toolkit 103 | *.gpState 104 | 105 | # ReSharper is a .NET coding add-in 106 | _ReSharper*/ 107 | *.[Rr]e[Ss]harper 108 | *.DotSettings.user 109 | 110 | # JustCode is a .NET coding add-in 111 | .JustCode 112 | 113 | # TeamCity is a build add-in 114 | _TeamCity* 115 | 116 | # DotCover is a Code Coverage Tool 117 | *.dotCover 118 | 119 | # Visual Studio code coverage results 120 | *.coverage 121 | *.coveragexml 122 | 123 | # NCrunch 124 | _NCrunch_* 125 | .*crunch*.local.xml 126 | nCrunchTemp_* 127 | 128 | # MightyMoose 129 | *.mm.* 130 | AutoTest.Net/ 131 | 132 | # Web workbench (sass) 133 | .sass-cache/ 134 | 135 | # Installshield output folder 136 | [Ee]xpress/ 137 | 138 | # DocProject is a documentation generator add-in 139 | DocProject/buildhelp/ 140 | DocProject/Help/*.HxT 141 | DocProject/Help/*.HxC 142 | DocProject/Help/*.hhc 143 | DocProject/Help/*.hhk 144 | DocProject/Help/*.hhp 145 | DocProject/Help/Html2 146 | DocProject/Help/html 147 | 148 | # Click-Once directory 149 | publish/ 150 | 151 | # Publish Web Output 152 | *.[Pp]ublish.xml 153 | *.azurePubxml 154 | # TODO: Comment the next line if you want to checkin your web deploy settings 155 | # but database connection strings (with potential passwords) will be unencrypted 156 | *.pubxml 157 | *.publishproj 158 | 159 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 160 | # checkin your Azure Web App publish settings, but sensitive information contained 161 | # in these scripts will be unencrypted 162 | PublishScripts/ 163 | 164 | # NuGet Packages 165 | *.nupkg 166 | # The packages folder can be ignored because of Package Restore 167 | **/packages/* 168 | # except build/, which is used as an MSBuild target. 169 | !**/packages/build/ 170 | # Uncomment if necessary however generally it will be regenerated when needed 171 | #!**/packages/repositories.config 172 | # NuGet v3's project.json files produces more ignorable files 173 | *.nuget.props 174 | *.nuget.targets 175 | 176 | # Microsoft Azure Build Output 177 | csx/ 178 | *.build.csdef 179 | 180 | # Microsoft Azure Emulator 181 | ecf/ 182 | rcf/ 183 | 184 | # Windows Store app package directories and files 185 | AppPackages/ 186 | BundleArtifacts/ 187 | Package.StoreAssociation.xml 188 | _pkginfo.txt 189 | *.appx 190 | 191 | # Visual Studio cache files 192 | # files ending in .cache can be ignored 193 | *.[Cc]ache 194 | # but keep track of directories ending in .cache 195 | !*.[Cc]ache/ 196 | 197 | # Others 198 | ClientBin/ 199 | ~$* 200 | *~ 201 | *.dbmdl 202 | *.dbproj.schemaview 203 | *.jfm 204 | *.pfx 205 | *.publishsettings 206 | orleans.codegen.cs 207 | 208 | # Since there are multiple workflows, uncomment next line to ignore bower_components 209 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 210 | #bower_components/ 211 | 212 | # RIA/Silverlight projects 213 | Generated_Code/ 214 | 215 | # Backup & report files from converting an old project file 216 | # to a newer Visual Studio version. Backup files are not needed, 217 | # because we have git ;-) 218 | _UpgradeReport_Files/ 219 | Backup*/ 220 | UpgradeLog*.XML 221 | UpgradeLog*.htm 222 | 223 | # SQL Server files 224 | *.mdf 225 | *.ldf 226 | *.ndf 227 | 228 | # Business Intelligence projects 229 | *.rdl.data 230 | *.bim.layout 231 | *.bim_*.settings 232 | 233 | # Microsoft Fakes 234 | FakesAssemblies/ 235 | 236 | # GhostDoc plugin setting file 237 | *.GhostDoc.xml 238 | 239 | # Node.js Tools for Visual Studio 240 | .ntvs_analysis.dat 241 | node_modules/ 242 | 243 | # Typescript v1 declaration files 244 | typings/ 245 | 246 | # Visual Studio 6 build log 247 | *.plg 248 | 249 | # Visual Studio 6 workspace options file 250 | *.opt 251 | 252 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 253 | *.vbw 254 | 255 | # Visual Studio LightSwitch build output 256 | **/*.HTMLClient/GeneratedArtifacts 257 | **/*.DesktopClient/GeneratedArtifacts 258 | **/*.DesktopClient/ModelManifest.xml 259 | **/*.Server/GeneratedArtifacts 260 | **/*.Server/ModelManifest.xml 261 | _Pvt_Extensions 262 | 263 | # Paket dependency manager 264 | .paket/paket.exe 265 | paket-files/ 266 | 267 | # FAKE - F# Make 268 | .fake/ 269 | 270 | # JetBrains Rider 271 | .idea/ 272 | *.sln.iml 273 | 274 | # CodeRush 275 | .cr/ 276 | 277 | # Python Tools for Visual Studio (PTVS) 278 | __pycache__/ 279 | *.pyc 280 | 281 | # Cake - Uncomment if you are using it 282 | # tools/** 283 | # !tools/packages.config 284 | 285 | # Tabs Studio 286 | *.tss 287 | 288 | # Telerik's JustMock configuration file 289 | *.jmconfig 290 | 291 | # BizTalk build output 292 | *.btp.cs 293 | *.btm.cs 294 | *.odx.cs 295 | *.xsd.cs 296 | 297 | *.cache 298 | SAMPLauncherNET/obj/Debug/SAMPLauncherNET.csproj.FileListAbsolute.txt 299 | SAMPLauncherNET/bin/ 300 | SAMPLauncherNET/obj/ 301 | SAMPLauncherNET/PreBuilds/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | solution: ./SAMPLauncherNET.sln 3 | 4 | install: 5 | - sudo apt-get install nunit-console 6 | - nuget restore ./SAMPLauncherNET.sln 7 | 8 | script: 9 | - xbuild ./SAMPLauncherNET.sln 10 | -------------------------------------------------------------------------------- /.vs/SAMPLauncherNET/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/.vs/SAMPLauncherNET/v15/.suo -------------------------------------------------------------------------------- /FEATURES.md: -------------------------------------------------------------------------------- 1 | # SAMPLauncherNET 2 | 3 | ![Screenshot](screenshots/screenshot001.png) 4 | 5 | ## Features 6 | 7 | ### Backwards compatibility 8 | Most features that are present in the native SA:MP launcher are present in this application. 9 | 10 | ### Modernized look 11 | With the use of the Material Design layout the launcher looks modern. 12 | 13 | ### Multi-language support 14 | If you prefer a different language than the english language, you can easily change the language of the launcher. 15 | 16 | ### ASI plugin loader and manager 17 | Load or manage any GTA San Andreas compatible ASI plugin within this launcher. 18 | Enable plugins in the plugins manager tab. 19 | Supported and listed ASI plugins by default: 20 | - [SA:MP Discord Rich Presence plugin](https://github.com/Hual/samp-discord-plugin) 21 | 22 | ### Multi-threaded query mechanism 23 | Fast server listing, where hundreds of SA:MP servers can be queried at the same time. 24 | 25 | ### Show extended server information 26 | List any relevant information of a server for example modes or server location with a couple of clicks. 27 | 28 | ### Improved server filter 29 | Search for your beloved server fast and easily 30 | 31 | ### Search engines integration 32 | Search anything related to a SA:MP server easily on popular search engines. 33 | 34 | ### Debug mode and singleplayer 35 | You can launch SA:MP debug mode or Grand Theft Auto San Andreas with a click on a button. 36 | 37 | ### Media 38 | The media tab allows to manage screenshots, look up the last chatlog and saved positions. 39 | 40 | ### Sessions data 41 | A very important feature for users who want to record session based data. 42 | This can be enabled at the launcher options. 43 | 44 | ### Version changer 45 | Change your SA:MP version to your needs by applying a patch or installing manually. 46 | 47 | ### SA:MP settings 48 | Change your SA:MP settings through an user interface. 49 | 50 | ### Server list APIs 51 | Manage your server list endpoints, and access lists that were inaccessible through a launcher before. 52 | 53 | ### Developer tools 54 | Make your server development workflow easier by configuring, starting and joining your test server using the [sampctl](https://sampctl.com/) integration. 55 | 56 | ## Screenshots 57 | 58 | ![Screenshot](screenshots/screenshot001.png) 59 | 60 | ![Screenshot](screenshots/screenshot002.png) 61 | 62 | ![Screenshot](screenshots/screenshot003.png) 63 | 64 | ![Screenshot](screenshots/screenshot004.png) 65 | 66 | ![Screenshot](screenshots/screenshot005.png) 67 | 68 | ![Screenshot](screenshots/screenshot006.png) 69 | 70 | ![Screenshot](screenshots/screenshot007.png) 71 | 72 | ![Screenshot](screenshots/screenshot008.png) 73 | 74 | ![Screenshot](screenshots/screenshot009.png) 75 | 76 | ![Screenshot](screenshots/screenshot010.png) 77 | 78 | ![Screenshot](screenshots/screenshot011.png) 79 | 80 | ![Screenshot](screenshots/screenshot012.png) 81 | 82 | ![Screenshot](screenshots/screenshot013.png) 83 | 84 | ![Screenshot](screenshots/screenshot014.png) 85 | 86 | ![Screenshot](screenshots/screenshot015.png) 87 | 88 | ![Screenshot](screenshots/screenshot016.png) 89 | 90 | ![Screenshot](screenshots/screenshot017.png) 91 | 92 | ![Screenshot](screenshots/screenshot018.png) 93 | 94 | ![Screenshot](screenshots/screenshot019.png) 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SAMPLauncherNET 2 | [![Build Status](https://travis-ci.org/BigETI/SAMPLauncherNET.svg?branch=master)](https://travis-ci.org/BigETI/SAMPLauncherNET) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/dd6f650fe9c141f88ae8d60f64712802)](https://www.codacy.com/app/BigETI/SAMPLauncherNET?utm_source=github.com&utm_medium=referral&utm_content=BigETI/SAMPLauncherNET&utm_campaign=Badge_Grade) 3 | 4 | ## Description 5 | SAMPLauncherNET is a launcher for San Andreas Multiplayer 6 | 7 | ## Why not the native San Andreas Multiplayer launcher? 8 | SAMPLauncherNET is a more modern approach to San Andreas Multiplayer. 9 | It is capable to do more things than the native San Andreas Multiplayer launcher. 10 | 11 | ## How to use it? 12 | Download and move the binaries into any directory you prefer, which should have read and write permissions. 13 | 14 | ## Where can I get a current build of SAMPLauncherNET? 15 | You can check the releases out in https://github.com/BigETI/SAMPLauncherNET/releases 16 | 17 | ## What features does it provide? 18 | Check out the launcher [features](https://github.com/BigETI/SAMPLauncherNET/blob/master/FEATURES.md) at https://github.com/BigETI/SAMPLauncherNET/blob/master/FEATURES.md 19 | 20 | ## How to contribute to this project? 21 | Fork this project, commit your changes and create a pull request. 22 | 23 | ### Translation 24 | Translation files are located at https://github.com/BigETI/SAMPLauncherNET/tree/master/SAMPLauncherNET/languages , 25 | pick up `en-GB.json`, create a copy 26 | and rename it to the language's `language tag` you want to translate. 27 | https://msdn.microsoft.com/en-us/library/cc233982.aspx 28 | For example the `language tag` of spanish in Spain is `es-ES`. 29 | 30 | ### Code 31 | You can change anything within the source code to contribute. 32 | 33 | ## Projects associated with this project 34 | - https://github.com/BigETI/INIEngine 35 | - https://github.com/BigETI/UpdaterNET 36 | - https://github.com/BigETI/WinFormsTranslator 37 | - https://github.com/errepi/ude 38 | - https://github.com/icsharpcode/SharpZipLib 39 | - https://github.com/IgnaceMaes/MaterialSkin 40 | - https://github.com/Hual/samp-discord-plugin 41 | - https://github.com/Southclaws/samp-servers-api 42 | - https://github.com/Southclaws/sampctl 43 | 44 | ## Similar projects 45 | - https://github.com/Bios-Marcel/ServerBrowser 46 | - https://github.com/earlwlkr/SAMP-Launcher-vi 47 | - https://github.com/Papawy/SAMP_Ex 48 | - https://github.com/Papawy/SAMP_Ex2 49 | - https://github.com/pasvitas/Samp-Launcher 50 | - https://github.com/jasarsoft/launcher-samp 51 | - https://github.com/Whitetigerswt/samp_launcher 52 | 53 | ## Projects you want to check out 54 | - https://github.com/BigETI/sampcmd 55 | - https://github.com/BigETI/SAMPcmdNET 56 | - https://github.com/Southclaws/samp-servers-frontend 57 | -------------------------------------------------------------------------------- /SAMPLauncherNET.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27004.2009 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAMPLauncherNET", "SAMPLauncherNET\SAMPLauncherNET.csproj", "{1BD42D89-52F4-45A5-8EA9-369B695938C2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Debug|x64.ActiveCfg = Debug|Any CPU 21 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Debug|x64.Build.0 = Debug|Any CPU 22 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Debug|x86.ActiveCfg = Debug|Any CPU 23 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Debug|x86.Build.0 = Debug|Any CPU 24 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Release|x64.ActiveCfg = Release|Any CPU 27 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Release|x64.Build.0 = Release|Any CPU 28 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Release|x86.ActiveCfg = Release|Any CPU 29 | {1BD42D89-52F4-45A5-8EA9-369B695938C2}.Release|x86.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {92C0D9F7-C0E0-4BE5-A53E-FDF97D0FAEFC} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/delete_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/delete_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/edit_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/edit_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/github_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/github_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/github_large_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/github_large_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/install_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/install_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/new_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/new_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/open_folder_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/open_folder_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/patch_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/patch_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/samp-hd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/samp-hd.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/samp-inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/samp-inactive.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/samp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/samp.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/samp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/samp_logo.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Images/view_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/Images/view_icon.png -------------------------------------------------------------------------------- /SAMPLauncherNET/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die einer Assembly zugeordnet sind. 8 | [assembly: AssemblyTitle("SAMPLauncherNET")] 9 | [assembly: AssemblyDescription("SAMPLauncherNET is a launcher for San Andreas Multiplayer")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SAMPLauncherNET")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly 18 | // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("1bd42d89-52f4-45a5-8ea9-369b695938c2")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.7.0")] 36 | [assembly: AssemblyFileVersion("1.0.7.0")] 37 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Dieser Code wurde von einem Tool generiert. 4 | // Laufzeitversion:4.0.30319.42000 5 | // 6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn 7 | // der Code erneut generiert wird. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SAMPLauncherNET.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.6.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 | } 27 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SAMPLauncherNET/SAMPLauncherNET.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | publish\ 9 | 10 | 11 | 12 | 13 | 14 | de-DE 15 | false 16 | 17 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/APIDataContract.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// API data contract 10 | /// 11 | [DataContract] 12 | public class APIDataContract 13 | { 14 | /// 15 | /// API name 16 | /// 17 | [DataMember] 18 | private string name; 19 | 20 | /// 21 | /// API type 22 | /// 23 | [DataMember] 24 | private string type; 25 | 26 | /// 27 | /// API endpoint 28 | /// 29 | [DataMember] 30 | private string endpoint; 31 | 32 | /// 33 | /// API name 34 | /// 35 | public string Name 36 | { 37 | get 38 | { 39 | return name; 40 | } 41 | } 42 | 43 | /// 44 | /// API type 45 | /// 46 | public string Type 47 | { 48 | get 49 | { 50 | return type; 51 | } 52 | } 53 | 54 | /// 55 | /// API endpoint 56 | /// 57 | public string Endpoint 58 | { 59 | get 60 | { 61 | return endpoint; 62 | } 63 | } 64 | 65 | /// 66 | /// Default constructor 67 | /// 68 | public APIDataContract() 69 | { 70 | // 71 | } 72 | 73 | /// 74 | /// Constructor 75 | /// 76 | /// Name 77 | /// Type 78 | /// Endpoint 79 | public APIDataContract(string name, string type, string endpoint) 80 | { 81 | this.name = name; 82 | this.type = type; 83 | this.endpoint = endpoint; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/EChatlogFormatType.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Chatlog format type enumerator 8 | /// 9 | public enum EChatlogFormatType 10 | { 11 | /// 12 | /// Plain text 13 | /// 14 | /// 15 | /// Coloring is not supported 16 | /// 17 | Plain, 18 | 19 | /// 20 | /// Rich text format 21 | /// 22 | RTF, 23 | 24 | /// 25 | /// HTML snippet 26 | /// 27 | HTMLSnippet, 28 | 29 | /// 30 | /// HTML document 31 | /// 32 | HTML 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/EPluginProvider.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Plugin provider enumerator 8 | /// 9 | public enum EPluginProvider 10 | { 11 | /// 12 | /// URI 13 | /// 14 | URI, 15 | 16 | /// 17 | /// Access build using the GitHub API 18 | /// 19 | GitHub 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/ERequestResponseType.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Request or response type enumerator 8 | /// 9 | public enum ERequestResponseType 10 | { 11 | /// 12 | /// Ping 13 | /// 14 | Ping, 15 | 16 | /// 17 | /// Information 18 | /// 19 | Information, 20 | 21 | /// 22 | /// Rules 23 | /// 24 | Rules, 25 | 26 | /// 27 | /// Clients 28 | /// 29 | Clients, 30 | 31 | /// 32 | /// Detailed clients 33 | /// 34 | DetailedClients 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/EServerListType.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Server list type enumerator 8 | /// 9 | public enum EServerListType 10 | { 11 | /// 12 | /// Favourites 13 | /// 14 | Favourites, 15 | 16 | /// 17 | /// Backend RESTful 18 | /// 19 | BackendRESTful, 20 | 21 | /// 22 | /// Legacy favourites 23 | /// 24 | LegacyFavourites, 25 | 26 | /// 27 | /// Legacy SA:MP 28 | /// 29 | LegacySAMP, 30 | 31 | /// 32 | /// Error 33 | /// 34 | Error 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/EUpdateFrequency.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Update frequency enumerator 8 | /// 9 | public enum EUpdateFrequency 10 | { 11 | /// 12 | /// If missing 13 | /// 14 | IfMissing, 15 | 16 | /// 17 | /// When newer 18 | /// 19 | /// 20 | /// Only works with GitHub provider 21 | /// 22 | WhenNewer, 23 | 24 | /// 25 | /// Always at launch 26 | /// 27 | Always 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/FavouriteDataContract.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// Favourite data contract class 10 | /// 11 | [DataContract] 12 | public class FavouriteDataContract 13 | { 14 | /// 15 | /// Host 16 | /// 17 | [DataMember] 18 | private string host; 19 | 20 | /// 21 | /// Hostname 22 | /// 23 | [DataMember] 24 | private string hostname; 25 | 26 | /// 27 | /// Mode 28 | /// 29 | [DataMember] 30 | private string mode; 31 | 32 | /// 33 | /// Host 34 | /// 35 | public string Host 36 | { 37 | get 38 | { 39 | if (host == null) 40 | { 41 | host = ""; 42 | } 43 | return host; 44 | } 45 | } 46 | 47 | /// 48 | /// Hostname 49 | /// 50 | public string Hostname 51 | { 52 | get 53 | { 54 | if (hostname == null) 55 | { 56 | hostname = ""; 57 | } 58 | return hostname; 59 | } 60 | } 61 | 62 | /// 63 | /// Mode 64 | /// 65 | public string Mode 66 | { 67 | get 68 | { 69 | if (mode == null) 70 | { 71 | mode = ""; 72 | } 73 | return mode; 74 | } 75 | } 76 | 77 | /// 78 | /// Default constructor 79 | /// 80 | public FavouriteDataContract() 81 | { 82 | // 83 | } 84 | 85 | /// 86 | /// Constructor 87 | /// 88 | /// Host 89 | /// Hostname 90 | /// Mode 91 | public FavouriteDataContract(string host, string hostname, string mode) 92 | { 93 | this.host = host; 94 | this.hostname = hostname; 95 | this.mode = mode; 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/FavouriteServer.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Favourite server 8 | /// 9 | public class FavouriteServer : Server 10 | { 11 | /// 12 | /// Server password 13 | /// 14 | private readonly string serverPassword; 15 | 16 | /// 17 | /// RCON password 18 | /// 19 | private readonly string rconPassword; 20 | 21 | /// 22 | /// Server password 23 | /// 24 | public string ServerPassword 25 | { 26 | get 27 | { 28 | return serverPassword; 29 | } 30 | } 31 | 32 | /// 33 | /// RCON password 34 | /// 35 | public string RCONPassword 36 | { 37 | get 38 | { 39 | return rconPassword; 40 | } 41 | } 42 | 43 | /// 44 | /// Constructor 45 | /// 46 | /// IP address and port string 47 | /// Cached hostname 48 | /// Cached gamemode 49 | /// Server password 50 | /// RCON password 51 | public FavouriteServer(string ipAddressAndPortString, string cachedHostname, string cachedGamemode, string serverPassword, string rconPassword) : base(ipAddressAndPortString, false) 52 | { 53 | if (cachedHostname != null) 54 | { 55 | if (cachedHostname.Trim().Length > 0) 56 | { 57 | hostname = cachedHostname; 58 | } 59 | } 60 | gamemode = cachedGamemode; 61 | this.serverPassword = serverPassword; 62 | this.rconPassword = rconPassword; 63 | FetchDataAsync(ERequestResponseType.Ping); 64 | FetchDataAsync(ERequestResponseType.Information); 65 | } 66 | 67 | /// 68 | /// Constructor 69 | /// 70 | /// Favorite data contract 71 | public FavouriteServer(FavouriteDataContract fdc) : base(fdc.Host, false) 72 | { 73 | if (fdc.Hostname.Trim().Length > 0) 74 | { 75 | hostname = fdc.Hostname; 76 | } 77 | serverPassword = ""; 78 | rconPassword = ""; 79 | FetchDataAsync(ERequestResponseType.Ping); 80 | FetchDataAsync(ERequestResponseType.Information); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/FileResource.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// File resource class 8 | /// 9 | public class FileResource 10 | { 11 | /// 12 | /// Path 13 | /// 14 | private readonly string path; 15 | 16 | /// 17 | /// Path 18 | /// 19 | public string Path 20 | { 21 | get 22 | { 23 | return path; 24 | } 25 | } 26 | 27 | /// 28 | /// File name 29 | /// 30 | public string FileName 31 | { 32 | get 33 | { 34 | return System.IO.Path.GetFileName(path); 35 | } 36 | } 37 | 38 | /// 39 | /// File name without extension 40 | /// 41 | public string FileNameWithoutExtension 42 | { 43 | get 44 | { 45 | return System.IO.Path.GetFileNameWithoutExtension(path); 46 | } 47 | } 48 | 49 | /// 50 | /// Constructor 51 | /// 52 | /// Path 53 | public FileResource(string path) 54 | { 55 | this.path = path; 56 | } 57 | 58 | /// 59 | /// To string 60 | /// 61 | /// String representation 62 | public override string ToString() 63 | { 64 | return FileNameWithoutExtension; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/FileState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | /// 5 | /// SA:MP launcher .NET namespace 6 | /// 7 | namespace SAMPLauncherNET 8 | { 9 | /// 10 | /// File state class 11 | /// 12 | public class FileState 13 | { 14 | /// 15 | /// Path 16 | /// 17 | private string path; 18 | 19 | /// 20 | /// Last write date and time 21 | /// 22 | private DateTime lastWriteDateTime; 23 | 24 | /// 25 | /// Path 26 | /// 27 | public string Path 28 | { 29 | get 30 | { 31 | return path; 32 | } 33 | } 34 | 35 | /// 36 | /// Last write date and time 37 | /// 38 | public DateTime LastWriteDateTime 39 | { 40 | get 41 | { 42 | return lastWriteDateTime; 43 | } 44 | } 45 | 46 | /// 47 | /// Constructor 48 | /// 49 | /// Path 50 | public FileState(string path) 51 | { 52 | this.path = path; 53 | if (File.Exists(path)) 54 | { 55 | try 56 | { 57 | lastWriteDateTime = File.GetLastWriteTime(path); 58 | } 59 | catch (Exception e) 60 | { 61 | lastWriteDateTime = DateTime.Now; 62 | Console.Error.WriteLine(e); 63 | } 64 | } 65 | else 66 | { 67 | lastWriteDateTime = DateTime.Now; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/FilterOption.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Filter option 8 | /// 9 | public class FilterOption 10 | { 11 | /// 12 | /// Field 13 | /// 14 | private string field; 15 | 16 | /// 17 | /// Display name 18 | /// 19 | private string displayName; 20 | 21 | /// 22 | /// Field 23 | /// 24 | public string Field 25 | { 26 | get => field; 27 | set 28 | { 29 | if (value != null) 30 | { 31 | field = value; 32 | } 33 | } 34 | } 35 | 36 | /// 37 | /// Display name 38 | /// 39 | public string DisplayName 40 | { 41 | get => displayName; 42 | set 43 | { 44 | if (value != null) 45 | { 46 | displayName = value; 47 | } 48 | } 49 | } 50 | 51 | /// 52 | /// Constrcutor 53 | /// 54 | public FilterOption() 55 | { 56 | field = ""; 57 | displayName = ""; 58 | } 59 | 60 | /// 61 | /// Constrcutor 62 | /// 63 | /// Field 64 | /// Display name 65 | public FilterOption(string field, string displayName) 66 | { 67 | this.field = field; 68 | this.displayName = displayName; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/FreeGeoIPDataContract.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// Free geo IP data contract class 10 | /// 11 | [DataContract] 12 | public class FreeGeoIPDataContract 13 | { 14 | /// 15 | /// IP 16 | /// 17 | [DataMember(Name = "ip")] 18 | private string ip = null; 19 | 20 | /// 21 | /// Country code 22 | /// 23 | [DataMember(Name = "country_code")] 24 | private string countryCode = null; 25 | 26 | /// 27 | /// Country name 28 | /// 29 | [DataMember(Name = "country_name")] 30 | private string countryName = null; 31 | 32 | /// 33 | /// Region code 34 | /// 35 | [DataMember(Name = "region_code")] 36 | private string regionCode = null; 37 | 38 | /// 39 | /// Region name 40 | /// 41 | [DataMember(Name = "region_name")] 42 | private string regionName = null; 43 | 44 | /// 45 | /// City 46 | /// 47 | [DataMember(Name = "city")] 48 | private string city = null; 49 | 50 | /// 51 | /// ZIP code 52 | /// 53 | [DataMember(Name = "zip_code")] 54 | private string zipCode = null; 55 | 56 | /// 57 | /// Time zone 58 | /// 59 | [DataMember(Name = "time_zone")] 60 | private string timeZone = null; 61 | 62 | /// 63 | /// Latitude 64 | /// 65 | [DataMember(Name = "latitude")] 66 | private float latitude = 0.0f; 67 | 68 | /// 69 | /// Longitude 70 | /// 71 | [DataMember(Name = "longitude")] 72 | private float longitude = 0.0f; 73 | 74 | /// 75 | /// Metro code 76 | /// 77 | [DataMember(Name = "metro_code")] 78 | private int metroCode = 0; 79 | 80 | /// 81 | /// IP 82 | /// 83 | public string IP 84 | { 85 | get 86 | { 87 | return ip; 88 | } 89 | } 90 | 91 | /// 92 | /// Country code 93 | /// 94 | public string CountryCode 95 | { 96 | get 97 | { 98 | return countryCode; 99 | } 100 | } 101 | 102 | /// 103 | /// Country name 104 | /// 105 | public string CountryName 106 | { 107 | get 108 | { 109 | return countryName; 110 | } 111 | } 112 | 113 | /// 114 | /// Region code 115 | /// 116 | public string RegionCode 117 | { 118 | get 119 | { 120 | return regionCode; 121 | } 122 | } 123 | 124 | /// 125 | /// Region name 126 | /// 127 | public string RegionName 128 | { 129 | get 130 | { 131 | return regionName; 132 | } 133 | } 134 | 135 | /// 136 | /// City 137 | /// 138 | public string City 139 | { 140 | get 141 | { 142 | return city; 143 | } 144 | } 145 | 146 | /// 147 | /// ZIP code 148 | /// 149 | public string ZIPCode 150 | { 151 | get 152 | { 153 | return zipCode; 154 | } 155 | } 156 | 157 | /// 158 | /// Time zone 159 | /// 160 | public string TimeZone 161 | { 162 | get 163 | { 164 | return timeZone; 165 | } 166 | } 167 | 168 | /// 169 | /// Latitude 170 | /// 171 | public float Latitude 172 | { 173 | get 174 | { 175 | return latitude; 176 | } 177 | } 178 | 179 | /// 180 | /// Longitude 181 | /// 182 | public float Longitude 183 | { 184 | get 185 | { 186 | return longitude; 187 | } 188 | } 189 | 190 | /// 191 | /// Metro code 192 | /// 193 | public int MetroCode 194 | { 195 | get 196 | { 197 | return metroCode; 198 | } 199 | } 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/GeoLocationData.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Geo location data 8 | /// 9 | public class GeoLocationData 10 | { 11 | /// 12 | /// Is valid 13 | /// 14 | private readonly bool isValid; 15 | 16 | /// 17 | /// IP 18 | /// 19 | private readonly string ip = ""; 20 | 21 | /// 22 | /// Country code 23 | /// 24 | private readonly string countryCode = ""; 25 | 26 | /// 27 | /// Country name 28 | /// 29 | private readonly string countryName = ""; 30 | 31 | /// 32 | /// Region name 33 | /// 34 | private readonly string regionName = ""; 35 | 36 | /// 37 | /// Region code 38 | /// 39 | private readonly string regionCode = ""; 40 | 41 | /// 42 | /// City 43 | /// 44 | private readonly string city = ""; 45 | 46 | /// 47 | /// ZIP code 48 | /// 49 | private readonly string zipCode = ""; 50 | 51 | /// 52 | /// Time zone 53 | /// 54 | private readonly string timeZone = ""; 55 | 56 | /// 57 | /// Latitude 58 | /// 59 | private readonly float latitude; 60 | 61 | /// 62 | /// Longitude 63 | /// 64 | private readonly float longitude; 65 | 66 | /// 67 | /// Metro code 68 | /// 69 | private readonly int metroCode; 70 | 71 | /// 72 | /// Is valid 73 | /// 74 | public bool IsValid 75 | { 76 | get 77 | { 78 | return isValid; 79 | } 80 | } 81 | 82 | /// 83 | /// IP 84 | /// 85 | public string IP 86 | { 87 | get 88 | { 89 | return ip; 90 | } 91 | } 92 | 93 | /// 94 | /// Country code 95 | /// 96 | public string CountryCode 97 | { 98 | get 99 | { 100 | return countryCode; 101 | } 102 | } 103 | 104 | /// 105 | /// Country name 106 | /// 107 | public string CountryName 108 | { 109 | get 110 | { 111 | return countryName; 112 | } 113 | } 114 | 115 | /// 116 | /// Region name 117 | /// 118 | public string RegionName 119 | { 120 | get 121 | { 122 | return regionName; 123 | } 124 | } 125 | 126 | /// 127 | /// Region code 128 | /// 129 | public string RegionCode 130 | { 131 | get 132 | { 133 | return regionCode; 134 | } 135 | } 136 | 137 | /// 138 | /// City 139 | /// 140 | public string City 141 | { 142 | get 143 | { 144 | return city; 145 | } 146 | } 147 | 148 | /// 149 | /// ZIP code 150 | /// 151 | public string ZIPCode 152 | { 153 | get 154 | { 155 | return zipCode; 156 | } 157 | } 158 | 159 | /// 160 | /// Time zone 161 | /// 162 | public string TimeZone 163 | { 164 | get 165 | { 166 | return timeZone; 167 | } 168 | } 169 | 170 | /// 171 | /// Latitude 172 | /// 173 | public float Latitude 174 | { 175 | get 176 | { 177 | return latitude; 178 | } 179 | } 180 | 181 | /// 182 | /// Longitude 183 | /// 184 | public float Longitude 185 | { 186 | get 187 | { 188 | return longitude; 189 | } 190 | } 191 | 192 | /// 193 | /// Metro code 194 | /// 195 | public int MetroCode 196 | { 197 | get 198 | { 199 | return metroCode; 200 | } 201 | } 202 | 203 | /// 204 | /// Constructor 205 | /// 206 | /// Result 207 | public GeoLocationData(object result) 208 | { 209 | if (result != null) 210 | { 211 | if (result is FreeGeoIPDataContract) 212 | { 213 | FreeGeoIPDataContract freeGeoIPData = (FreeGeoIPDataContract)result; 214 | isValid = true; 215 | ip = Utils.NAString(freeGeoIPData.IP); 216 | countryCode = Utils.NAString(freeGeoIPData.CountryCode); 217 | countryName = Utils.NAString(freeGeoIPData.CountryName); 218 | regionName = Utils.NAString(freeGeoIPData.RegionName); 219 | regionCode = Utils.NAString(freeGeoIPData.RegionCode); 220 | city = Utils.NAString(freeGeoIPData.City); 221 | zipCode = Utils.NAString(freeGeoIPData.ZIPCode); 222 | timeZone = Utils.NAString(freeGeoIPData.TimeZone); 223 | latitude = freeGeoIPData.Latitude; 224 | longitude = freeGeoIPData.Longitude; 225 | metroCode = freeGeoIPData.MetroCode; 226 | } 227 | } 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/GeoLocationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Runtime.Serialization.Json; 5 | 6 | /// 7 | /// SA:MP launcher .NET namespace 8 | /// 9 | namespace SAMPLauncherNET 10 | { 11 | /// 12 | /// Geo location provider 13 | /// 14 | public class GeoLocationProvider 15 | { 16 | /// 17 | /// Endpoint 18 | /// 19 | private readonly string endpoint; 20 | 21 | /// 22 | /// Serializer 23 | /// 24 | private readonly DataContractJsonSerializer serializer; 25 | 26 | /// 27 | /// Constructor 28 | /// 29 | /// Endpoint 30 | /// Serialization type 31 | public GeoLocationProvider(string endpoint, Type serializationType) 32 | { 33 | this.endpoint = endpoint; 34 | serializer = new DataContractJsonSerializer(serializationType); 35 | } 36 | 37 | /// 38 | /// Request data 39 | /// 40 | /// Host 41 | /// Geo location data 42 | public GeoLocationData RequestData(string host) 43 | { 44 | GeoLocationData ret = null; 45 | try 46 | { 47 | WebClientEx wc = new WebClientEx(1000); 48 | wc.Headers.Set(HttpRequestHeader.Accept, "application/json"); 49 | wc.Headers.Set(HttpRequestHeader.UserAgent, SAMPProvider.UserAgent); 50 | using (MemoryStream stream = new MemoryStream(wc.DownloadData(endpoint + host))) 51 | { 52 | object result = serializer.ReadObject(stream); 53 | if (result != null) 54 | { 55 | ret = new GeoLocationData(result); 56 | } 57 | } 58 | } 59 | catch (Exception e) 60 | { 61 | Console.Error.WriteLine(e); 62 | } 63 | return ret; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/GeoLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | 4 | /// 5 | /// SA:MP launcher .NET namespace 6 | /// 7 | namespace SAMPLauncherNET 8 | { 9 | /// 10 | /// Geo locator class 11 | /// 12 | public static class GeoLocator 13 | { 14 | /// 15 | /// Cache 16 | /// 17 | private static Dictionary cache = new Dictionary(); 18 | 19 | /// 20 | /// Providers 21 | /// 22 | private static readonly GeoLocationProvider[] providers = new [] { new GeoLocationProvider("http://freegeoip.net/json/", typeof(FreeGeoIPDataContract)) }; 23 | 24 | /// 25 | /// Locate 26 | /// 27 | /// Host 28 | /// Geo location data 29 | public static GeoLocationData Locate(string host) 30 | { 31 | GeoLocationData ret = null; 32 | string h = host.Trim(); 33 | if (cache.ContainsKey(h)) 34 | { 35 | ret = cache[h]; 36 | } 37 | else 38 | { 39 | foreach (GeoLocationProvider provider in providers) 40 | { 41 | ret = provider.RequestData(h); 42 | if (ret != null) 43 | { 44 | break; 45 | } 46 | } 47 | } 48 | if (ret == null) 49 | { 50 | ret = new GeoLocationData(null); 51 | } 52 | return ret; 53 | } 54 | 55 | /// 56 | /// Locate asynchronous 57 | /// 58 | /// Host 59 | /// Geo location data 60 | public static Task LocateAsync(string host) 61 | { 62 | return Task.Factory.StartNew(() => Locate(host)); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/IndexedServerListConnector.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Indexed server list connector 8 | /// 9 | public class IndexedServerListConnector 10 | { 11 | /// 12 | /// Server list connector 13 | /// 14 | private readonly ServerListConnector serverListConnector; 15 | 16 | /// 17 | /// Index 18 | /// 19 | private readonly int index; 20 | 21 | /// 22 | /// Server list connector 23 | /// 24 | public ServerListConnector ServerListConnector 25 | { 26 | get 27 | { 28 | return serverListConnector; 29 | } 30 | } 31 | 32 | /// 33 | /// Index 34 | /// 35 | public int Index 36 | { 37 | get 38 | { 39 | return index; 40 | } 41 | } 42 | 43 | /// 44 | /// Constructor 45 | /// 46 | /// Server list connector 47 | /// Index 48 | public IndexedServerListConnector(ServerListConnector serverListConnector, int index) 49 | { 50 | this.serverListConnector = serverListConnector; 51 | this.index = index; 52 | } 53 | 54 | /// 55 | /// To string 56 | /// 57 | /// String representation 58 | public override string ToString() 59 | { 60 | return serverListConnector.ToString(); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/InstalledPlugin.cs: -------------------------------------------------------------------------------- 1 | using UpdaterNET; 2 | /// 3 | /// SA:MP launcher .NET namespace 4 | /// 5 | namespace SAMPLauncherNET 6 | { 7 | /// 8 | /// Installed plugin class 9 | /// 10 | public class InstalledPlugin 11 | { 12 | /// 13 | /// Path 14 | /// 15 | private string path = ""; 16 | 17 | /// 18 | /// Last release information 19 | /// 20 | private GitHubLatestReleaseDataContract lastReleaseInfo; 21 | 22 | /// 23 | /// Latest release information 24 | /// 25 | private GitHubLatestReleaseDataContract latestReleaseInfo; 26 | 27 | /// 28 | /// Path 29 | /// 30 | public string Path 31 | { 32 | get 33 | { 34 | return path; 35 | } 36 | } 37 | 38 | /// 39 | /// Last release information 40 | /// 41 | public GitHubLatestReleaseDataContract LastReleaseInfo 42 | { 43 | get 44 | { 45 | return lastReleaseInfo; 46 | } 47 | } 48 | 49 | /// 50 | /// Latest release information 51 | /// 52 | public GitHubLatestReleaseDataContract LatestReleaseInfo 53 | { 54 | get 55 | { 56 | return latestReleaseInfo; 57 | } 58 | } 59 | 60 | /// 61 | /// Constructor 62 | /// 63 | /// Path 64 | public InstalledPlugin(string path) 65 | { 66 | this.path = path; 67 | } 68 | 69 | /// 70 | /// Constructor 71 | /// 72 | /// Path 73 | /// Last release information 74 | /// Latest release information 75 | public InstalledPlugin(string path, GitHubLatestReleaseDataContract lastReleaseInfo, GitHubLatestReleaseDataContract latestReleaseInfo) 76 | { 77 | this.path = path; 78 | this.lastReleaseInfo = lastReleaseInfo; 79 | this.latestReleaseInfo = latestReleaseInfo; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/MediaState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | /// 6 | /// SA:MP launcher.NET namespace 7 | /// 8 | namespace SAMPLauncherNET 9 | { 10 | /// 11 | /// Media state class 12 | /// 13 | public class MediaState 14 | { 15 | /// 16 | /// Paths 17 | /// 18 | private string[] paths; 19 | 20 | /// 21 | /// File states 22 | /// 23 | private Dictionary fileStates = new Dictionary(); 24 | 25 | /// 26 | /// Media state 27 | /// 28 | public MediaState(params string[] paths) 29 | { 30 | if (paths == null) 31 | { 32 | this.paths = new string[0]; 33 | } 34 | if (paths != null) 35 | { 36 | this.paths = paths; 37 | foreach (string path in paths) 38 | { 39 | AddFilesState(path); 40 | } 41 | } 42 | } 43 | 44 | /// 45 | /// Add files state 46 | /// 47 | /// Path 48 | private void AddFilesState(string path) 49 | { 50 | try 51 | { 52 | if (path != null) 53 | { 54 | if (Directory.Exists(path)) 55 | { 56 | string[] paths = Directory.GetFiles(path); 57 | if (paths != null) 58 | { 59 | foreach (string p in paths) 60 | { 61 | AddFilesState(p); 62 | } 63 | } 64 | } 65 | else if (File.Exists(path)) 66 | { 67 | fileStates.Add(path, new FileState(path)); 68 | } 69 | } 70 | } 71 | catch (Exception e) 72 | { 73 | Console.Error.WriteLine(e); 74 | } 75 | } 76 | 77 | /// 78 | /// Get files 79 | /// 80 | /// File or directory path 81 | /// File paths 82 | private IEnumerable GetFiles(string path) 83 | { 84 | List ret = new List(); 85 | try 86 | { 87 | if (path != null) 88 | { 89 | if (Directory.Exists(path)) 90 | { 91 | string[] paths = Directory.GetFiles(path); 92 | if (paths != null) 93 | { 94 | foreach (string p in paths) 95 | { 96 | ret.AddRange(GetFiles(p)); 97 | } 98 | } 99 | } 100 | else if (File.Exists(path)) 101 | { 102 | ret.Add(path); 103 | } 104 | } 105 | } 106 | catch (Exception e) 107 | { 108 | Console.Error.WriteLine(e); 109 | } 110 | return ret; 111 | } 112 | 113 | /// 114 | /// Get modified or added file paths 115 | /// 116 | /// File paths 117 | public string[] GetModifiedAdded() 118 | { 119 | List ret = new List(); 120 | List paths = new List(); 121 | foreach (string path in this.paths) 122 | { 123 | paths.AddRange(GetFiles(path)); 124 | } 125 | foreach (string path in paths) 126 | { 127 | if (fileStates.ContainsKey(path)) 128 | { 129 | try 130 | { 131 | // Check for modified 132 | DateTime last_write_date_time = File.GetLastWriteTime(path); 133 | if (last_write_date_time > fileStates[path].LastWriteDateTime) 134 | { 135 | ret.Add(path); 136 | } 137 | } 138 | catch (Exception e) 139 | { 140 | Console.Error.WriteLine(e); 141 | } 142 | } 143 | else 144 | { 145 | ret.Add(path); 146 | } 147 | } 148 | return ret.ToArray(); 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/OnFilterEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// On filter event handler delegate 10 | /// 11 | /// Sender 12 | /// Event arguments 13 | public delegate void OnFilterEventHandler(object sender, EventArgs e); 14 | } 15 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/PingString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// Ping string class 10 | /// 11 | public class PingString : IComparable, IComparable 12 | { 13 | /// 14 | /// Ping 15 | /// 16 | private readonly uint ping; 17 | 18 | /// 19 | /// Constructor 20 | /// 21 | /// Ping 22 | public PingString(uint ping) 23 | { 24 | this.ping = ping; 25 | } 26 | 27 | /// 28 | /// Compare to 29 | /// 30 | /// Object 31 | /// Result 32 | public int CompareTo(object obj) 33 | { 34 | int ret = 1; 35 | if (obj != null) 36 | { 37 | ret = CompareTo(obj as PingString); 38 | } 39 | return ret; 40 | } 41 | 42 | /// 43 | /// CompareTo 44 | /// 45 | /// Other 46 | /// Result 47 | public int CompareTo(PingString other) 48 | { 49 | int ret = 1; 50 | if (other != null) 51 | { 52 | ret = ping.CompareTo(other.ping); 53 | } 54 | return ret; 55 | } 56 | 57 | /// 58 | /// To string 59 | /// 60 | /// String representation 61 | public override string ToString() 62 | { 63 | return ((ping == uint.MaxValue) ? "-" : ping.ToString()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/Player.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Player class 8 | /// 9 | public class Player 10 | { 11 | /// 12 | /// ID 13 | /// 14 | private readonly byte id; 15 | 16 | /// 17 | /// Name 18 | /// 19 | private readonly string name; 20 | 21 | /// 22 | /// Score 23 | /// 24 | private readonly int score; 25 | 26 | /// 27 | /// Ping 28 | /// 29 | private readonly uint ping; 30 | 31 | /// 32 | /// ID 33 | /// 34 | public byte ID 35 | { 36 | get 37 | { 38 | return id; 39 | } 40 | } 41 | 42 | /// 43 | /// Name 44 | /// 45 | public string Name 46 | { 47 | get 48 | { 49 | return name; 50 | } 51 | } 52 | 53 | /// 54 | /// Score 55 | /// 56 | public int Score 57 | { 58 | get 59 | { 60 | return score; 61 | } 62 | } 63 | 64 | /// 65 | /// Ping 66 | /// 67 | public uint Ping 68 | { 69 | get 70 | { 71 | return ping; 72 | } 73 | } 74 | 75 | /// 76 | /// Constructor 77 | /// 78 | /// ID 79 | /// Name 80 | /// Score 81 | /// Ping 82 | public Player(byte id, string name, int score, uint ping) 83 | { 84 | this.id = id; 85 | this.name = name; 86 | this.score = score; 87 | this.ping = ping; 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/PlayerCountString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// Player count string class 10 | /// 11 | public class PlayerCountString : IComparable, IComparable 12 | { 13 | /// 14 | /// Player count 15 | /// 16 | private readonly uint playerCount; 17 | 18 | /// 19 | /// Max players 20 | /// 21 | private readonly uint maxPlayers; 22 | 23 | /// 24 | /// Constructor 25 | /// 26 | /// Player count 27 | /// Max players 28 | public PlayerCountString(uint playerCount, uint maxPlayers) 29 | { 30 | this.playerCount = playerCount; 31 | this.maxPlayers = maxPlayers; 32 | } 33 | 34 | /// 35 | /// Compare to 36 | /// 37 | /// Object 38 | /// Result 39 | public int CompareTo(object obj) 40 | { 41 | int ret = 1; 42 | if (obj != null) 43 | { 44 | ret = CompareTo(obj as PlayerCountString); 45 | } 46 | return ret; 47 | } 48 | 49 | /// 50 | /// CompareTo 51 | /// 52 | /// Other 53 | /// Result 54 | public int CompareTo(PlayerCountString other) 55 | { 56 | int ret = 1; 57 | if (other != null) 58 | { 59 | if (playerCount == other.playerCount) 60 | { 61 | ret = ((maxPlayers == other.maxPlayers) ? 0 : ((maxPlayers > other.maxPlayers) ? 1 : -1)); 62 | } 63 | else 64 | { 65 | ret = ((playerCount > other.playerCount) ? 1 : -1); 66 | } 67 | } 68 | return ret; 69 | } 70 | 71 | /// 72 | /// To string 73 | /// 74 | /// String representation 75 | public override string ToString() 76 | { 77 | return playerCount + "/" + maxPlayers; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/RequestsRequired.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// Requests required class 10 | /// 11 | public class RequestsRequired 12 | { 13 | /// 14 | /// Request type count 15 | /// 16 | private static readonly int requestTypeCount = Enum.GetValues(typeof(ERequestResponseType)).Length; 17 | 18 | /// 19 | /// Values 20 | /// 21 | private readonly bool[] values; 22 | 23 | /// 24 | /// Available 25 | /// 26 | private readonly bool[] available; 27 | 28 | /// 29 | /// Last request time 30 | /// 31 | private readonly DateTime[] lastRequestTime; 32 | 33 | /// 34 | /// Operation codes 35 | /// 36 | private static readonly char[] opCodes = new [] { 'p', 'i', 'r', 'c', 'd' }; 37 | 38 | /// 39 | /// Array element access operator 40 | /// 41 | /// Request type 42 | /// Request required 43 | public bool this[ERequestResponseType requestType] 44 | { 45 | get 46 | { 47 | return values[(int)requestType]; 48 | } 49 | set 50 | { 51 | if (available[(int)requestType]) 52 | { 53 | values[(int)requestType] = value; 54 | } 55 | } 56 | } 57 | 58 | /// 59 | /// Get operation code 60 | /// 61 | /// Request type 62 | /// Operation code 63 | public static char GetOpCode(ERequestResponseType requestType) 64 | { 65 | return opCodes[(int)requestType]; 66 | } 67 | 68 | /// 69 | /// Constructor 70 | /// 71 | /// Initial value 72 | public RequestsRequired(bool initialValue) 73 | { 74 | int i; 75 | DateTime now = DateTime.Now; 76 | values = new bool[requestTypeCount]; 77 | lastRequestTime = new DateTime[values.Length]; 78 | available = new bool[values.Length]; 79 | for (i = 0; i < values.Length; i++) 80 | { 81 | values[i] = initialValue; 82 | lastRequestTime[i] = now; 83 | available[i] = true; 84 | } 85 | } 86 | 87 | /// 88 | /// Get last request time 89 | /// 90 | /// Request type 91 | /// Last request time 92 | public DateTime GetLastRequestTime(ERequestResponseType requestType) 93 | { 94 | return lastRequestTime[(int)requestType]; 95 | } 96 | 97 | /// 98 | /// Set last request time 99 | /// 100 | /// Request type 101 | public void SetLastRequestTime(ERequestResponseType requestType) 102 | { 103 | lastRequestTime[(int)requestType] = DateTime.Now; 104 | } 105 | 106 | /// 107 | /// Lock 108 | /// 109 | /// Request type 110 | public void Lock(ERequestResponseType requestType) 111 | { 112 | available[(int)requestType] = false; 113 | values[(int)requestType] = false; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/SAMPProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Net; 5 | using System.Runtime.Serialization.Json; 6 | using System.Security.Cryptography; 7 | 8 | /// 9 | /// SA:MP launcher .NET namespace 10 | /// 11 | namespace SAMPLauncherNET 12 | { 13 | /// 14 | /// SA:MP provider class 15 | /// 16 | public static class SAMPProvider 17 | { 18 | /// 19 | /// Versions URI 20 | /// 24 | /// API HTTP content type 25 | /// 26 | private static readonly string APIHTTPContentType = "text/html"; 27 | 28 | /// 29 | /// API HTTP accept 30 | /// 31 | private static readonly string APIHTTPAccept = "text/html, */*"; 32 | 33 | /// 34 | /// API HTTP user agent 35 | /// 36 | private static readonly string APIHTTPUserAgent = "Mozilla/3.0 (compatible; SA:MP launcher .NET)"; 37 | 38 | /// 39 | /// Current version 40 | /// 41 | private static SAMPVersionDataContract currentVersion; 42 | 43 | /// 44 | /// Version required 45 | /// 46 | private static bool versionRequired = true; 47 | 48 | /// 49 | /// Versions 50 | /// 51 | private static Dictionary versions; 52 | 53 | /// 54 | /// Versions 55 | /// 56 | public static Dictionary Versions 57 | { 58 | get 59 | { 60 | if (versions == null) 61 | { 62 | versions = new Dictionary(); 63 | try 64 | { 65 | using (WebClientEx wc = new WebClientEx(5000)) 66 | { 67 | wc.Headers.Set(HttpRequestHeader.ContentType, APIHTTPContentType); 68 | wc.Headers.Set(HttpRequestHeader.Accept, APIHTTPAccept); 69 | wc.Headers.Set(HttpRequestHeader.UserAgent, APIHTTPUserAgent); 70 | using (MemoryStream stream = new MemoryStream(wc.DownloadData(VersionsURI))) 71 | { 72 | DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List)); 73 | List samp_versions = serializer.ReadObject(stream) as List; 74 | if (samp_versions != null) 75 | { 76 | foreach (SAMPVersionDataContract version in samp_versions) 77 | { 78 | versions.Add(version.SAMPDLLSHA512, version); 79 | } 80 | } 81 | } 82 | } 83 | 84 | } 85 | catch (Exception e) 86 | { 87 | Console.Error.WriteLine(e); 88 | } 89 | } 90 | return versions; 91 | } 92 | } 93 | 94 | /// 95 | /// Versions list 96 | /// 97 | public static List VersionsList 98 | { 99 | get 100 | { 101 | List ret = new List(Versions.Values); 102 | ret.Sort(); 103 | return ret; 104 | } 105 | } 106 | 107 | /// 108 | /// Current Version 109 | /// 110 | public static SAMPVersionDataContract CurrentVersion 111 | { 112 | get 113 | { 114 | if (versionRequired) 115 | { 116 | versionRequired = false; 117 | try 118 | { 119 | if (File.Exists(SAMP.SAMPDLLPath)) 120 | { 121 | using (SHA512 sha512 = SHA512.Create()) 122 | { 123 | using (FileStream stream = new FileStream(SAMP.SAMPDLLPath, FileMode.Open)) 124 | { 125 | string key = Convert.ToBase64String(sha512.ComputeHash(stream)); 126 | if (Versions.ContainsKey(key)) 127 | { 128 | currentVersion = Versions[key]; 129 | } 130 | } 131 | } 132 | } 133 | } 134 | catch (Exception e) 135 | { 136 | Console.Error.WriteLine(e); 137 | } 138 | } 139 | return currentVersion; 140 | } 141 | } 142 | 143 | /// 144 | /// User agent 145 | /// 146 | public static string UserAgent 147 | { 148 | get 149 | { 150 | return ((CurrentVersion == null) ? APIHTTPUserAgent : CurrentVersion.UserAgent); 151 | } 152 | } 153 | 154 | /// 155 | /// Internet tab URI 156 | /// 157 | public static string InternetTabURI 158 | { 159 | get 160 | { 161 | return ((CurrentVersion == null) ? "" : CurrentVersion.InternetTabURI); 162 | } 163 | } 164 | 165 | /// 166 | /// Hosted tab URI 167 | /// 168 | public static string HostedTabURI 169 | { 170 | get 171 | { 172 | return ((CurrentVersion == null) ? "" : CurrentVersion.HostedTabURI); 173 | } 174 | } 175 | 176 | /// 177 | /// Official tab URI 178 | /// 179 | public static string OfficialTabURI 180 | { 181 | get 182 | { 183 | return ((CurrentVersion == null) ? "" : CurrentVersion.OfficialTabURI); 184 | } 185 | } 186 | 187 | /// 188 | /// Reset version cache 189 | /// 190 | public static void ResetVersionCache() 191 | { 192 | versionRequired = true; 193 | currentVersion = null; 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/SAMPServersAPIServer.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// SA:MP servers API server class 8 | /// 9 | public class SAMPServersAPIServer : Server 10 | { 11 | /// 12 | /// Constructor 13 | /// 14 | /// Server data 15 | public SAMPServersAPIServer(SAMPServersAPIServerDataContract serverData) : base(serverData.Host, false) 16 | { 17 | if (serverData.Hostname.Trim().Length > 0) 18 | { 19 | hostname = serverData.Hostname; 20 | } 21 | gamemode = serverData.Gamemode; 22 | playerCount = serverData.PlayerCount; 23 | maxPlayers = serverData.MaxPlayers; 24 | hasPassword = serverData.HasPassword; 25 | language = serverData.Language; 26 | FetchDataAsync(ERequestResponseType.Ping); 27 | FetchDataAsync(ERequestResponseType.Information); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/SAMPServersAPIServerDataContract.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// SA:MP servers API server data contract class 10 | /// 11 | [DataContract] 12 | public class SAMPServersAPIServerDataContract 13 | { 14 | /// 15 | /// Host 16 | /// 17 | [DataMember(Name = "ip")] 18 | private string host = ""; 19 | 20 | /// 21 | /// Hostname 22 | /// 23 | [DataMember(Name = "hn")] 24 | private string hostname = ""; 25 | 26 | /// 27 | /// Player count 28 | /// 29 | [DataMember(Name = "pc")] 30 | private ushort playerCount = 0; 31 | 32 | /// 33 | /// Maximal players 34 | /// 35 | [DataMember(Name = "pm")] 36 | private ushort maxPlayers = 0; 37 | 38 | /// 39 | /// Gamemode 40 | /// 41 | [DataMember(Name = "gm")] 42 | private string gamemode = ""; 43 | 44 | /// 45 | /// Language 46 | /// 47 | [DataMember(Name = "la")] 48 | private string language = ""; 49 | 50 | /// 51 | /// Has password 52 | /// 53 | [DataMember(Name = "pa")] 54 | private bool hasPassword = false; 55 | 56 | /// 57 | /// Version 58 | /// 59 | [DataMember(Name = "vn")] 60 | private string version = ""; 61 | 62 | /// 63 | /// Host 64 | /// 65 | public string Host 66 | { 67 | get 68 | { 69 | if (host == null) 70 | { 71 | host = ""; 72 | } 73 | return host; 74 | } 75 | } 76 | 77 | /// 78 | /// Hostname 79 | /// 80 | public string Hostname 81 | { 82 | get 83 | { 84 | if (hostname == null) 85 | { 86 | hostname = ""; 87 | } 88 | return hostname; 89 | } 90 | } 91 | 92 | /// 93 | /// Player count 94 | /// 95 | public ushort PlayerCount 96 | { 97 | get 98 | { 99 | return playerCount; 100 | } 101 | } 102 | 103 | /// 104 | /// Maximal players 105 | /// 106 | public ushort MaxPlayers 107 | { 108 | get 109 | { 110 | return maxPlayers; 111 | } 112 | } 113 | 114 | /// 115 | /// Gamemode 116 | /// 117 | public string Gamemode 118 | { 119 | get 120 | { 121 | if (gamemode == null) 122 | { 123 | gamemode = ""; 124 | } 125 | return gamemode; 126 | } 127 | } 128 | 129 | /// 130 | /// Language 131 | /// 132 | public string Language 133 | { 134 | get 135 | { 136 | if (language == null) 137 | { 138 | language = ""; 139 | } 140 | return language; 141 | } 142 | } 143 | 144 | /// 145 | /// Has password 146 | /// 147 | public bool HasPassword 148 | { 149 | get 150 | { 151 | return hasPassword; 152 | } 153 | } 154 | 155 | /// 156 | /// Version 157 | /// 158 | public string Version 159 | { 160 | get 161 | { 162 | if (version == null) 163 | { 164 | version = ""; 165 | } 166 | return version; 167 | } 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/SAMPVersionDataContract.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// SA:MP version 10 | /// 11 | [DataContract] 12 | public class SAMPVersionDataContract : IComparable 13 | { 14 | /// 15 | /// Name 16 | /// 17 | [DataMember] 18 | private readonly string name; 19 | 20 | /// 21 | /// Internet tap URI 22 | /// 23 | [DataMember] 24 | private readonly string internetTabURI; 25 | 26 | /// 27 | /// Hosted tab URI 28 | /// 29 | [DataMember] 30 | private readonly string hostedTabURI; 31 | 32 | /// 33 | /// Official tab URI 34 | /// 35 | [DataMember] 36 | private readonly string officialTabURI; 37 | 38 | /// 39 | /// User agent 40 | /// 41 | [DataMember] 42 | private readonly string userAgent; 43 | 44 | /// 45 | /// Zip URI 46 | /// 47 | [DataMember] 48 | private readonly string zipURI; 49 | 50 | /// 51 | /// Installation URI 52 | /// 53 | [DataMember] 54 | private readonly string installationURI; 55 | 56 | /// 57 | /// samp.dll SHA512 58 | /// 59 | [DataMember] 60 | private readonly string sampDLLSHA512; 61 | 62 | /// 63 | /// Order number 64 | /// 65 | [DataMember] 66 | private readonly uint orderNumber; 67 | 68 | /// 69 | /// Name 70 | /// 71 | public string Name 72 | { 73 | get 74 | { 75 | return name; 76 | } 77 | } 78 | 79 | /// 80 | /// Internet tab URI 81 | /// 82 | public string InternetTabURI 83 | { 84 | get 85 | { 86 | return internetTabURI; 87 | } 88 | } 89 | 90 | /// 91 | /// Hosted tab URI 92 | /// 93 | public string HostedTabURI 94 | { 95 | get 96 | { 97 | return hostedTabURI; 98 | } 99 | } 100 | 101 | /// 102 | /// Official tab URI 103 | /// 104 | public string OfficialTabURI 105 | { 106 | get 107 | { 108 | return officialTabURI; 109 | } 110 | } 111 | 112 | /// 113 | /// User agent 114 | /// 115 | public string UserAgent 116 | { 117 | get 118 | { 119 | return userAgent; 120 | } 121 | } 122 | 123 | /// 124 | /// Zip URI 125 | /// 126 | public string ZipURI 127 | { 128 | get 129 | { 130 | return zipURI; 131 | } 132 | } 133 | 134 | /// 135 | /// Installation URI 136 | /// 137 | public string InstallationURI 138 | { 139 | get 140 | { 141 | return installationURI; 142 | } 143 | } 144 | 145 | /// 146 | /// samp.dll SHA512 147 | /// 148 | public string SAMPDLLSHA512 149 | { 150 | get 151 | { 152 | return sampDLLSHA512; 153 | } 154 | } 155 | 156 | /// 157 | /// Constructor 158 | /// 159 | /// Name 160 | /// Internet tab URI 161 | /// Hosted tab URI 162 | /// Official tab URI 163 | /// User agent 164 | /// Zip URI 165 | /// Installation URI 166 | /// SA:MP DLL SHA512 167 | /// Order number 168 | public SAMPVersionDataContract(string name, string internetTabURI, string hostedTabURI, string officialTabURI, string userAgent, string zipURI, string installationURI, string sampDLLSHA512, uint orderNumber) 169 | { 170 | this.name = name; 171 | this.internetTabURI = internetTabURI; 172 | this.hostedTabURI = hostedTabURI; 173 | this.officialTabURI = officialTabURI; 174 | this.userAgent = userAgent; 175 | this.zipURI = zipURI; 176 | this.installationURI = installationURI; 177 | this.sampDLLSHA512 = sampDLLSHA512; 178 | this.orderNumber = orderNumber; 179 | } 180 | 181 | /// 182 | /// To string 183 | /// 184 | /// String representation 185 | public override string ToString() 186 | { 187 | return name; 188 | } 189 | 190 | /// 191 | /// Compare to 192 | /// 193 | /// Other 194 | /// Compared value 195 | public int CompareTo(SAMPVersionDataContract other) 196 | { 197 | int ret = -1; 198 | if (other != null) 199 | { 200 | ret = (int)(other.orderNumber - orderNumber); 201 | if (ret == 0) 202 | { 203 | ret = string.Compare(other.name, name, StringComparison.InvariantCulture); 204 | } 205 | } 206 | return ret; 207 | } 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/ServerListEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// Server list entry 10 | /// 11 | public class ServerListEntry : IComparable, IComparable, IDisposable 12 | { 13 | /// 14 | /// Server 15 | /// 16 | private readonly Server server; 17 | 18 | /// 19 | /// Server list index 20 | /// 21 | private readonly int serverListIndex; 22 | 23 | /// 24 | /// Tries 25 | /// 26 | private uint tries; 27 | 28 | /// 29 | /// Server 30 | /// 31 | public Server Server { get => server; } 32 | 33 | /// 34 | /// Server list index 35 | /// 36 | public int ServerListIndex { get => serverListIndex; } 37 | 38 | /// 39 | /// Tries 40 | /// 41 | public uint Tries { get => tries; } 42 | 43 | /// 44 | /// Constructor 45 | /// 46 | /// Server 47 | /// Server list index 48 | public ServerListEntry(Server server, int serverListIndex) 49 | { 50 | this.server = server; 51 | this.serverListIndex = serverListIndex; 52 | } 53 | 54 | /// 55 | /// Try send query 56 | /// 57 | public void TrySendQuery() 58 | { 59 | if (server != null) 60 | { 61 | bool tried = false; 62 | if (server.SendQueryWhenExpiredAsync(ERequestResponseType.Ping, 5000U)) 63 | { 64 | tried = true; 65 | } 66 | if (server.SendQueryWhenExpiredAsync(ERequestResponseType.Information, 5000U)) 67 | { 68 | tried = true; 69 | } 70 | if (tried) 71 | { 72 | ++tries; 73 | } 74 | } 75 | } 76 | 77 | /// 78 | /// Compare to 79 | /// 80 | /// Object 81 | /// Comparison result 82 | public int CompareTo(object obj) 83 | { 84 | return ((obj is ServerListEntry) ? CompareTo((ServerListEntry)obj) : -1); 85 | } 86 | 87 | /// 88 | /// Compare to 89 | /// 90 | /// Other 91 | /// Comparison result 92 | public int CompareTo(ServerListEntry other) 93 | { 94 | int ret = -1; 95 | if ((other != null) && (server != null)) 96 | { 97 | if (other.server != null) 98 | { 99 | ret = server.CompareTo(other.server); 100 | if (ret == 0) 101 | { 102 | ret = serverListIndex.CompareTo(other.serverListIndex); 103 | } 104 | } 105 | } 106 | return ret; 107 | } 108 | 109 | /// 110 | /// Dispose 111 | /// 112 | public void Dispose() 113 | { 114 | if (server != null) 115 | { 116 | server.Dispose(); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/ServerResponseDelegate.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// SA:MP launcher .NET namespace 3 | /// 4 | namespace SAMPLauncherNET 5 | { 6 | /// 7 | /// Server response delegate 8 | /// 9 | /// Server 10 | /// Response type 11 | public delegate void ServerResponseDelegate(Server server, ERequestResponseType responseType); 12 | } 13 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/SessionDataContract.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | /// 5 | /// SA:MP launcher .NET namespace 6 | /// 7 | namespace SAMPLauncherNET 8 | { 9 | /// 10 | /// Session data contract class 11 | /// 12 | [DataContract] 13 | public class SessionDataContract 14 | { 15 | /// 16 | /// Date and time 17 | /// 18 | [DataMember] 19 | private DateTime dateTime; 20 | 21 | /// 22 | /// Time span 23 | /// 24 | [DataMember] 25 | private TimeSpan timeSpan; 26 | 27 | /// 28 | /// Game version 29 | /// 30 | [DataMember] 31 | private string gameVersion; 32 | 33 | /// 34 | /// Username 35 | /// 36 | [DataMember] 37 | private string username; 38 | 39 | /// 40 | /// IP and port 41 | /// 42 | [DataMember] 43 | private string ipPort; 44 | 45 | /// 46 | /// Hostname 47 | /// 48 | [DataMember] 49 | private string hostname; 50 | 51 | /// 52 | /// Mode 53 | /// 54 | [DataMember] 55 | private string mode; 56 | 57 | /// 58 | /// Language 59 | /// 60 | [DataMember] 61 | private string language; 62 | 63 | /// 64 | /// Date and time 65 | /// 66 | public DateTime DateTime 67 | { 68 | get 69 | { 70 | return dateTime; 71 | } 72 | } 73 | 74 | /// 75 | /// Time span 76 | /// 77 | public TimeSpan TimeSpan 78 | { 79 | get 80 | { 81 | return timeSpan; 82 | } 83 | } 84 | 85 | /// 86 | /// Game version 87 | /// 88 | public string GameVersion 89 | { 90 | get 91 | { 92 | return gameVersion; 93 | } 94 | } 95 | 96 | /// 97 | /// Username 98 | /// 99 | public string Username 100 | { 101 | get 102 | { 103 | return username; 104 | } 105 | } 106 | 107 | /// 108 | /// IP and port 109 | /// 110 | public string IPPort 111 | { 112 | get 113 | { 114 | return ipPort; 115 | } 116 | } 117 | 118 | /// 119 | /// Hostname 120 | /// 121 | public string Hostname 122 | { 123 | get 124 | { 125 | return hostname; 126 | } 127 | } 128 | 129 | /// 130 | /// Mode 131 | /// 132 | public string Mode 133 | { 134 | get 135 | { 136 | return mode; 137 | } 138 | } 139 | 140 | /// 141 | /// Language 142 | /// 143 | public string Language 144 | { 145 | get 146 | { 147 | return language; 148 | } 149 | } 150 | 151 | /// 152 | /// Constructor 153 | /// 154 | /// Date and time 155 | /// Time span 156 | /// Game version 157 | /// Username 158 | /// IP and port 159 | /// Hostname 160 | /// Mode 161 | /// Language 162 | public SessionDataContract(DateTime dateTime, TimeSpan timeSpan, string gameVersion, string username, string ipPort, string hostname, string mode, string language) 163 | { 164 | this.dateTime = dateTime; 165 | this.timeSpan = timeSpan; 166 | this.gameVersion = gameVersion; 167 | this.username = username; 168 | this.ipPort = ipPort; 169 | this.hostname = hostname; 170 | this.mode = mode; 171 | this.language = language; 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/SessionProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | /// 6 | /// SA:MP launcher .NET namespace 7 | /// 8 | namespace SAMPLauncherNET 9 | { 10 | /// 11 | /// Session provider class 12 | /// 13 | public static class SessionProvider 14 | { 15 | /// 16 | /// Sessions directory 17 | /// 18 | private static readonly string sessionsDirectory = Path.GetFullPath("./sessions"); 19 | 20 | /// 21 | /// Sessions directory 22 | /// 23 | public static string SessionsDirectory 24 | { 25 | get 26 | { 27 | return sessionsDirectory; 28 | } 29 | } 30 | 31 | /// 32 | /// Sessions 33 | /// 34 | public static Session[] Sessions 35 | { 36 | get 37 | { 38 | List ret = new List(); 39 | try 40 | { 41 | if (Directory.Exists(sessionsDirectory)) 42 | { 43 | string[] files = Directory.GetFiles(sessionsDirectory, "*.samp-session", SearchOption.AllDirectories); 44 | if (files != null) 45 | { 46 | foreach (string file in files) 47 | { 48 | Session session = SessionsCache.GetSession(file); 49 | if (session != null) 50 | { 51 | ret.Add(session); 52 | } 53 | } 54 | } 55 | } 56 | } 57 | catch (Exception e) 58 | { 59 | Console.Error.WriteLine(e); 60 | } 61 | return ret.ToArray(); 62 | } 63 | } 64 | 65 | /// 66 | /// Get current media state 67 | /// 68 | /// Media state 69 | public static MediaState GetCurrentMediaState() 70 | { 71 | return new MediaState(SAMP.GalleryPath, SAMP.ChatlogPath, SAMP.SavedPositionsPath); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/SessionsCache.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | /// 4 | /// SA:MP launcher .NET namespace 5 | /// 6 | namespace SAMPLauncherNET 7 | { 8 | /// 9 | /// Sessions cache class 10 | /// 11 | public static class SessionsCache 12 | { 13 | /// 14 | /// Sessions 15 | /// 16 | private static Dictionary sessions = new Dictionary(); 17 | 18 | /// 19 | /// Get session 20 | /// 21 | /// Session path 22 | /// Session 23 | public static Session GetSession(string path) 24 | { 25 | Session ret = null; 26 | if (path != null) 27 | { 28 | string p = path.ToLower(); 29 | lock (sessions) 30 | { 31 | if (sessions.ContainsKey(p)) 32 | { 33 | ret = sessions[p]; 34 | } 35 | else 36 | { 37 | ret = Session.Load(path); 38 | if (ret != null) 39 | { 40 | sessions.Add(p, ret); 41 | } 42 | } 43 | } 44 | } 45 | return ret; 46 | } 47 | 48 | /// 49 | /// Clear session cache 50 | /// 51 | public static void Clear() 52 | { 53 | lock (sessions) 54 | { 55 | sessions.Clear(); 56 | } 57 | } 58 | 59 | /// 60 | /// Remove session from cache 61 | /// 62 | /// Session 63 | public static void Remove(Session session) 64 | { 65 | if (session != null) 66 | { 67 | string path = session.Path.ToLower(); 68 | if (sessions.ContainsKey(path)) 69 | { 70 | sessions.Remove(path); 71 | session.Dispose(); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/TaskbarProgress.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Windows.Forms; 4 | 5 | /// 6 | /// SA:MP launcher .NET namespace 7 | /// 8 | namespace SAMPLauncherNET 9 | { 10 | /// 11 | /// Taskbar progress 12 | /// 13 | public static class TaskbarProgress 14 | { 15 | /// 16 | /// Taskbar states enumerator 17 | /// 18 | public enum TaskbarStates 19 | { 20 | /// 21 | /// No progress 22 | /// 23 | NoProgress = 0, 24 | 25 | /// 26 | /// Indeterminate 27 | /// 28 | Indeterminate = 0x1, 29 | 30 | /// 31 | /// Normal 32 | /// 33 | Normal = 0x2, 34 | 35 | /// 36 | /// Error 37 | /// 38 | Error = 0x4, 39 | 40 | /// 41 | /// Paused 42 | /// 43 | Paused = 0x8 44 | } 45 | 46 | /// 47 | /// Taskbar list interface 48 | /// 49 | [ComImport()] 50 | [Guid("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")] 51 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 52 | private interface ITaskbarList3 53 | { 54 | // ITaskbarList 55 | 56 | /// 57 | /// Hr init 58 | /// 59 | [PreserveSig] 60 | void HrInit(); 61 | 62 | /// 63 | /// Add tab 64 | /// 65 | /// Window handle 66 | [PreserveSig] 67 | void AddTab(IntPtr hwnd); 68 | 69 | /// 70 | /// Delete tabe 71 | /// 72 | /// Window handle 73 | [PreserveSig] 74 | void DeleteTab(IntPtr hwnd); 75 | 76 | /// 77 | /// Activate tab 78 | /// 79 | /// Window handle 80 | [PreserveSig] 81 | void ActivateTab(IntPtr hwnd); 82 | 83 | /// 84 | /// Set active alternate 85 | /// 86 | /// Window handle 87 | [PreserveSig] 88 | void SetActiveAlt(IntPtr hwnd); 89 | 90 | // ITaskbarList2 91 | 92 | /// 93 | /// Mark fullscreen window 94 | /// 95 | /// Window handle 96 | /// Fullscreen 97 | [PreserveSig] 98 | void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen); 99 | 100 | // ITaskbarList3 101 | 102 | /// 103 | /// Set progress value 104 | /// 105 | /// Window handle 106 | /// Completed 107 | /// Total 108 | [PreserveSig] 109 | void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal); 110 | 111 | /// 112 | /// Set progress state 113 | /// 114 | /// Window handle 115 | /// Taskbar state 116 | [PreserveSig] 117 | void SetProgressState(IntPtr hwnd, TaskbarStates state); 118 | } 119 | 120 | /// 121 | /// Taskbar instance class 122 | /// 123 | [ComImport()] 124 | [Guid("56fdf344-fd6d-11d0-958a-006097c9a090")] 125 | [ClassInterface(ClassInterfaceType.None)] 126 | private class TaskbarInstance 127 | { 128 | // 129 | } 130 | 131 | /// 132 | /// Taskbar instance 133 | /// 134 | private static ITaskbarList3 taskbarInstance = (ITaskbarList3)new TaskbarInstance(); 135 | 136 | /// 137 | /// Taskbar supported 138 | /// 139 | private static bool taskbarSupported = Environment.OSVersion.Version >= new Version(6, 1); 140 | 141 | /// 142 | /// Set state 143 | /// 144 | /// Form 145 | /// Taskbar state 146 | public static void SetState(Form form, TaskbarStates taskbarState) 147 | { 148 | if (taskbarSupported) 149 | { 150 | taskbarInstance.SetProgressState(form.Handle, taskbarState); 151 | } 152 | } 153 | 154 | /// 155 | /// Set value 156 | /// 157 | /// Form 158 | /// Progress value 159 | /// Progress maximal 160 | public static void SetValue(Form form, double progressValue, double progressMax) 161 | { 162 | if (taskbarSupported) 163 | { 164 | taskbarInstance.SetProgressValue(form.Handle, (ulong)progressValue, (ulong)progressMax); 165 | } 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/ThumbnailsCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | 6 | /// 7 | /// SA:MP launcher .NET namespace 8 | /// 9 | namespace SAMPLauncherNET 10 | { 11 | /// 12 | /// Thumnails cache class 13 | /// 14 | public static class ThumbnailsCache 15 | { 16 | /// 17 | /// Cache 18 | /// 19 | private static Dictionary cache = new Dictionary(); 20 | 21 | /// 22 | /// Clear 23 | /// 24 | public static void Clear() 25 | { 26 | foreach (Image image in cache.Values) 27 | { 28 | image.Dispose(); 29 | } 30 | cache.Clear(); 31 | } 32 | 33 | /// 34 | /// Get thumbnail 35 | /// 36 | /// Path 37 | /// Image 38 | public static Image GetThumbnail(string path) 39 | { 40 | Image ret = null; 41 | string p = path.ToLowerInvariant(); 42 | if (cache.ContainsKey(p)) 43 | { 44 | ret = cache[p]; 45 | } 46 | else 47 | { 48 | if (File.Exists(p)) 49 | { 50 | try 51 | { 52 | if (Utils.IsFileAvailable(p)) 53 | { 54 | Image image = Image.FromFile(p); 55 | if (image != null) 56 | { 57 | ret = Utils.GetThumbnail(image); 58 | image.Dispose(); 59 | if (ret != null) 60 | { 61 | cache.Add(p, ret); 62 | } 63 | } 64 | } 65 | } 66 | catch (Exception e) 67 | { 68 | Console.Error.WriteLine(e); 69 | } 70 | } 71 | } 72 | return ret; 73 | } 74 | 75 | /// 76 | /// Remove from cache 77 | /// 78 | /// Path 79 | public static void RemoveFromCache(string path) 80 | { 81 | string p = path.ToLowerInvariant(); 82 | if (cache.ContainsKey(p)) 83 | { 84 | cache[p].Dispose(); 85 | cache.Remove(p); 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/Core/WebClientEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | /// 5 | /// SA:MP launcher .NET namespace 6 | /// 7 | namespace SAMPLauncherNET 8 | { 9 | /// 10 | /// Web client extended 11 | /// 12 | public class WebClientEx : WebClient 13 | { 14 | /// 15 | /// Timeout 16 | /// 17 | private readonly int timeout; 18 | 19 | /// 20 | /// Constructor 21 | /// 22 | /// Timeout 23 | public WebClientEx(int timeout) 24 | { 25 | this.timeout = timeout; 26 | } 27 | 28 | /// 29 | /// Get web request 30 | /// 31 | /// URI 32 | /// Web request 33 | protected override WebRequest GetWebRequest(Uri uri) 34 | { 35 | WebRequest w = base.GetWebRequest(uri); 36 | w.Timeout = timeout; 37 | return w; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Controls/FilterUserControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Controls/SessionServerUserControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SAMPLauncherNET.UI 2 | { 3 | partial class SessionServerUserControl 4 | { 5 | /// 6 | /// Erforderliche Designervariable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Verwendete Ressourcen bereinigen. 12 | /// 13 | /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Vom Komponenten-Designer generierter Code 24 | 25 | /// 26 | /// Erforderliche Methode für die Designerunterstützung. 27 | /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.mainFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel(); 33 | this.textLabel = new MaterialSkin.Controls.MaterialLabel(); 34 | this.connectButton = new MaterialSkin.Controls.MaterialRaisedButton(); 35 | this.tickTimer = new System.Windows.Forms.Timer(this.components); 36 | this.mainFlowLayoutPanel.SuspendLayout(); 37 | this.SuspendLayout(); 38 | // 39 | // mainFlowLayoutPanel 40 | // 41 | this.mainFlowLayoutPanel.Controls.Add(this.textLabel); 42 | this.mainFlowLayoutPanel.Controls.Add(this.connectButton); 43 | this.mainFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; 44 | this.mainFlowLayoutPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; 45 | this.mainFlowLayoutPanel.Location = new System.Drawing.Point(0, 0); 46 | this.mainFlowLayoutPanel.Name = "mainFlowLayoutPanel"; 47 | this.mainFlowLayoutPanel.Size = new System.Drawing.Size(800, 600); 48 | this.mainFlowLayoutPanel.TabIndex = 0; 49 | // 50 | // textLabel 51 | // 52 | this.textLabel.AutoSize = true; 53 | this.textLabel.Depth = 0; 54 | this.textLabel.Font = new System.Drawing.Font("Roboto", 11F); 55 | this.textLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); 56 | this.textLabel.Location = new System.Drawing.Point(3, 0); 57 | this.textLabel.MouseState = MaterialSkin.MouseState.HOVER; 58 | this.textLabel.Name = "textLabel"; 59 | this.textLabel.Size = new System.Drawing.Size(21, 19); 60 | this.textLabel.TabIndex = 0; 61 | this.textLabel.Text = "..."; 62 | // 63 | // connectButton 64 | // 65 | this.connectButton.AutoSize = true; 66 | this.connectButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 67 | this.connectButton.Depth = 0; 68 | this.connectButton.Icon = null; 69 | this.connectButton.Location = new System.Drawing.Point(3, 22); 70 | this.connectButton.MouseState = MaterialSkin.MouseState.HOVER; 71 | this.connectButton.Name = "connectButton"; 72 | this.connectButton.Primary = true; 73 | this.connectButton.Size = new System.Drawing.Size(109, 36); 74 | this.connectButton.TabIndex = 1; 75 | this.connectButton.Text = "{$CONNECT$}"; 76 | this.connectButton.UseVisualStyleBackColor = true; 77 | this.connectButton.Click += new System.EventHandler(this.connectButton_Click); 78 | // 79 | // tickTimer 80 | // 81 | this.tickTimer.Enabled = true; 82 | this.tickTimer.Interval = 500; 83 | this.tickTimer.Tick += new System.EventHandler(this.tickTimer_Tick); 84 | // 85 | // SessionServerUserControl 86 | // 87 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 88 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 89 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51))))); 90 | this.Controls.Add(this.mainFlowLayoutPanel); 91 | this.Name = "SessionServerUserControl"; 92 | this.Size = new System.Drawing.Size(800, 600); 93 | this.mainFlowLayoutPanel.ResumeLayout(false); 94 | this.mainFlowLayoutPanel.PerformLayout(); 95 | this.ResumeLayout(false); 96 | 97 | } 98 | 99 | #endregion 100 | 101 | private System.Windows.Forms.FlowLayoutPanel mainFlowLayoutPanel; 102 | private MaterialSkin.Controls.MaterialLabel textLabel; 103 | private MaterialSkin.Controls.MaterialRaisedButton connectButton; 104 | private System.Windows.Forms.Timer tickTimer; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Controls/SessionServerUserControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Windows.Forms; 4 | using WinFormsTranslator; 5 | 6 | /// 7 | /// SA:MP launcher .NET UI namespace 8 | /// 9 | namespace SAMPLauncherNET.UI 10 | { 11 | /// 12 | /// Session server user control class 13 | /// 14 | public partial class SessionServerUserControl : UserControl 15 | { 16 | /// 17 | /// Session 18 | /// 19 | private Session session; 20 | 21 | /// 22 | /// Main form 23 | /// 24 | private MainForm mainForm; 25 | 26 | /// 27 | /// Server thread 28 | /// 29 | private Thread serverThread; 30 | 31 | /// 32 | /// Server 33 | /// 34 | private Server server; 35 | 36 | /// 37 | /// Hostname 38 | /// 39 | private string hostname; 40 | 41 | /// 42 | /// Mode 43 | /// 44 | private string mode; 45 | 46 | /// 47 | /// Language 48 | /// 49 | private string language; 50 | 51 | /// 52 | /// Username translated 53 | /// 54 | private string usernameTranslated; 55 | 56 | /// 57 | /// Game version translated 58 | /// 59 | private string gameVersionTranslated; 60 | 61 | /// 62 | /// Hostname translated 63 | /// 64 | private string hostnameTranslated; 65 | 66 | /// 67 | /// gamemode translated 68 | /// 69 | private string gamemodeTranslated; 70 | 71 | /// 72 | /// Language translated 73 | /// 74 | private string languageTranslated; 75 | 76 | /// 77 | /// Date and time translated 78 | /// 79 | private string dateAndTimeTranslated; 80 | 81 | /// 82 | /// Time spend translated 83 | /// 84 | private string timeSpendTranslated; 85 | 86 | /// 87 | /// Constructor 88 | /// 89 | /// Session 90 | public SessionServerUserControl(Session session, MainForm mainForm) 91 | { 92 | this.session = session; 93 | this.mainForm = mainForm; 94 | InitializeComponent(); 95 | Utils.Translator.TranslateControls(this); 96 | usernameTranslated = Utils.Translator.GetTranslation("USERNAME"); 97 | gameVersionTranslated = Utils.Translator.GetTranslation("GAME_VERSION"); 98 | hostnameTranslated = Utils.Translator.GetTranslation("HOSTNAME"); 99 | gamemodeTranslated = Utils.Translator.GetTranslation("GAMEMODE"); 100 | languageTranslated = Utils.Translator.GetTranslation("LANGUAGE"); 101 | dateAndTimeTranslated = Utils.Translator.GetTranslation("DATE_AND_TIME"); 102 | timeSpendTranslated = Utils.Translator.GetTranslation("TIME_SPEND"); 103 | 104 | hostname = session.Hostname; 105 | mode = session.Mode; 106 | language = session.Language; 107 | Disposed += (sender, e) => 108 | { 109 | if (serverThread != null) 110 | { 111 | serverThread.Abort(); 112 | serverThread = null; 113 | } 114 | }; 115 | serverThread = new Thread(() => 116 | { 117 | server = new Server(session.IPPort, true); 118 | if (server.IsValid) 119 | { 120 | while (true) 121 | { 122 | string hostname = server.Hostname; 123 | string mode = server.Gamemode; 124 | string language = server.Language; 125 | if (hostname.Length > 0) 126 | { 127 | this.hostname = hostname; 128 | } 129 | if (mode.Length > 0) 130 | { 131 | this.mode = mode; 132 | } 133 | if (language.Length > 0) 134 | { 135 | this.language = language; 136 | } 137 | Thread.Sleep(2000); 138 | } 139 | } 140 | server.Dispose(); 141 | server = null; 142 | }); 143 | serverThread.Start(); 144 | UpdateTextLabel(); 145 | } 146 | 147 | /// 148 | /// Update text label 149 | /// 150 | private void UpdateTextLabel() 151 | { 152 | textLabel.Text = usernameTranslated + ": " + session.Username + Environment.NewLine + Environment.NewLine + gameVersionTranslated + ": " + session.GameVersion + Environment.NewLine + Environment.NewLine + hostnameTranslated + ": " + hostname + Environment.NewLine + Environment.NewLine + gamemodeTranslated + ": " + mode + Environment.NewLine + Environment.NewLine + languageTranslated + ": " + language + Environment.NewLine + Environment.NewLine + dateAndTimeTranslated + ": " + session.DateTime + Environment.NewLine + Environment.NewLine + timeSpendTranslated + ": " + session.TimeSpan; 153 | } 154 | 155 | /// 156 | /// Conbnect button click event 157 | /// 158 | /// Sender 159 | /// Event arguments 160 | private void connectButton_Click(object sender, EventArgs e) 161 | { 162 | mainForm.ConnectUsingSession(session); 163 | } 164 | 165 | /// 166 | /// Tick timer tick event 167 | /// 168 | /// Sender 169 | /// Event arguments 170 | private void tickTimer_Tick(object sender, EventArgs e) 171 | { 172 | UpdateTextLabel(); 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Controls/SessionServerUserControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Controls/SessionUserControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 387, 17 122 | 123 | 124 | 118, 17 125 | 126 | 127 | 17, 17 128 | 129 | 130 | 258, 17 131 | 132 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/APIForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.Windows.Forms; 4 | using WinFormsTranslator; 5 | 6 | /// 7 | /// SA:MP launcher .NET namespace 8 | /// 9 | namespace SAMPLauncherNET 10 | { 11 | /// 12 | /// API form class 13 | /// 14 | public partial class APIForm : MaterialForm 15 | { 16 | /// 17 | /// API 18 | /// 19 | public APIDataContract API 20 | { 21 | get 22 | { 23 | return new APIDataContract(apiNameSingleLineTextField.Text, ((EServerListType)(apiTypeComboBox.SelectedIndex)).ToString(), apiEndpointSingleLineTextField.Text); 24 | } 25 | } 26 | 27 | /// 28 | /// Default constructor 29 | /// 30 | /// 31 | public APIForm(APIDataContract api) 32 | { 33 | InitializeComponent(); 34 | Utils.Translator.TranslateControls(this); 35 | Translator.EnumToComboBox(apiTypeComboBox, new EServerListType[] { EServerListType.Error }); 36 | if (api != null) 37 | { 38 | Text = Utils.Translator.GetTranslation("EDIT_API_TITLE"); 39 | apiNameSingleLineTextField.Text = api.Name; 40 | EServerListType type; 41 | if (!(Enum.TryParse(api.Type, out type))) 42 | { 43 | type = EServerListType.Favourites; 44 | } 45 | apiTypeComboBox.SelectedIndex = (int)type; 46 | apiEndpointSingleLineTextField.Text = api.Endpoint; 47 | } 48 | } 49 | 50 | /// 51 | /// Accept input 52 | /// 53 | private void AcceptInput() 54 | { 55 | if (apiNameSingleLineTextField.Text.Trim().Length <= 0) 56 | { 57 | MessageBox.Show(Utils.Translator.GetTranslation("API_NAME_MISSING"), Utils.Translator.GetTranslation("API_NAME_MISSING_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 58 | } 59 | else 60 | { 61 | if (apiTypeComboBox.SelectedIndex < 0) 62 | { 63 | MessageBox.Show(Utils.Translator.GetTranslation("API_TYPE_MISSING"), Utils.Translator.GetTranslation("API_TYPE_MISSING_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 64 | } 65 | else 66 | { 67 | if (apiEndpointSingleLineTextField.Text.Trim().Length <= 0) 68 | { 69 | MessageBox.Show(Utils.Translator.GetTranslation("API_ENDPOINT_MISSING"), Utils.Translator.GetTranslation("API_ENDPOINT_MISSING_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 70 | } 71 | else 72 | { 73 | DialogResult = DialogResult.OK; 74 | Close(); 75 | } 76 | } 77 | } 78 | } 79 | 80 | /// 81 | /// API name single line text field key up event 82 | /// 83 | /// Sender 84 | /// Key event arguments 85 | private void apiNameSingleLineTextField_KeyUp(object sender, KeyEventArgs e) 86 | { 87 | if (e.KeyCode == Keys.Return) 88 | { 89 | AcceptInput(); 90 | } 91 | else if (e.KeyCode == Keys.Escape) 92 | { 93 | Close(); 94 | } 95 | } 96 | 97 | /// 98 | /// OK button click event 99 | /// 100 | /// Sender 101 | /// Event arguments 102 | private void okButton_Click(object sender, EventArgs e) 103 | { 104 | AcceptInput(); 105 | } 106 | 107 | /// 108 | /// Cancel button click event 109 | /// 110 | /// Sender 111 | /// Event arguments 112 | private void cancelButton_Click(object sender, EventArgs e) 113 | { 114 | Close(); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/AddAddressToFavouriteListForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Windows.Forms; 6 | using WinFormsTranslator; 7 | 8 | /// 9 | /// SA:MP launcher .NET namespace 10 | /// 11 | namespace SAMPLauncherNET 12 | { 13 | /// 14 | /// Add address to favourites form class 15 | /// 16 | public partial class AddAddressToFavouriteListForm : MaterialForm 17 | { 18 | /// 19 | /// Address 20 | /// 21 | public string Address 22 | { 23 | get 24 | { 25 | return addressSingleLineTextField.Text; 26 | } 27 | } 28 | 29 | /// 30 | /// Selected server list connector 31 | /// 32 | public IndexedServerListConnector SelectedServerListConnector 33 | { 34 | get 35 | { 36 | return (IndexedServerListConnector)(favouritesListComboBox.SelectedItem); 37 | } 38 | } 39 | 40 | /// 41 | /// Constructor 42 | /// 43 | /// Favourites list 44 | public AddAddressToFavouriteListForm(IEnumerable favouriteLists) 45 | { 46 | InitializeComponent(); 47 | Utils.Translator.TranslateControls(this); 48 | favouritesListComboBox.Items.AddRange(favouriteLists.ToArray()); 49 | } 50 | 51 | /// 52 | /// OK button click event 53 | /// 54 | /// Sender 55 | /// Event arguments 56 | private void okButton_Click(object sender, EventArgs e) 57 | { 58 | if (SelectedServerListConnector == null) 59 | { 60 | MessageBox.Show(Utils.Translator.GetTranslation("FAVOURITE_LIST_NOT_SELECTED"), Utils.Translator.GetTranslation("FAVOURITE_LIST_NOT_SELECTED_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 61 | } 62 | else if (Address.Trim().Length <= 0) 63 | { 64 | MessageBox.Show(Utils.Translator.GetTranslation("NO_ADDRESS_SPECIFIED"), Utils.Translator.GetTranslation("NO_ADDRESS_SPECIFIED_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 65 | } 66 | else 67 | { 68 | DialogResult = DialogResult.OK; 69 | Close(); 70 | } 71 | } 72 | 73 | /// 74 | /// Cancel button click event 75 | /// 76 | /// Sender 77 | /// Event arguments 78 | private void cancelButton_Click(object sender, EventArgs e) 79 | { 80 | Close(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/ConnectForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.Drawing; 4 | using System.Windows.Forms; 5 | using WinFormsTranslator; 6 | 7 | /// 8 | /// SA:MP launcher .NET namespace 9 | /// 10 | namespace SAMPLauncherNET 11 | { 12 | /// 13 | /// Connect form class 14 | /// 15 | public partial class ConnectForm : MaterialForm 16 | { 17 | /// 18 | /// Username 19 | /// 20 | public string Username 21 | { 22 | get 23 | { 24 | return usernameSingleLineTextField.Text.Trim(); 25 | } 26 | } 27 | 28 | /// 29 | /// Server password 30 | /// 31 | public string ServerPassword 32 | { 33 | get 34 | { 35 | return serverPasswordSingleLineTextField.Text; 36 | } 37 | } 38 | 39 | /// 40 | /// Constructor 41 | /// 42 | /// No password mode 43 | public ConnectForm(bool noPasswordMode) 44 | { 45 | InitializeComponent(); 46 | Utils.Translator.TranslateControls(this); 47 | usernameSingleLineTextField.Text = SAMP.Username; 48 | if (noPasswordMode) 49 | { 50 | serverPasswordLabel.Visible = false; 51 | serverPasswordSingleLineTextField.Visible = false; 52 | Size sz = new Size(MinimumSize.Width, MinimumSize.Height - 55); 53 | MaximumSize = sz; 54 | MinimumSize = sz; 55 | } 56 | } 57 | 58 | /// 59 | /// Accept input 60 | /// 61 | private void AcceptInput() 62 | { 63 | if (Username.Length <= 0) 64 | { 65 | MessageBox.Show(Utils.Translator.GetTranslation("PLEASE_TYPE_IN_USERNAME"), Utils.Translator.GetTranslation("INPUT_ERROR"), MessageBoxButtons.OK, MessageBoxIcon.Error); 66 | } 67 | else 68 | { 69 | bool success = true; 70 | if (serverPasswordSingleLineTextField.Visible && (ServerPassword.Trim().Length <= 0)) 71 | { 72 | success = (MessageBox.Show(Utils.Translator.GetTranslation("SERVER_PASSWORD_FIELD_IS_EMPTY"), Utils.Translator.GetTranslation("SERVER_PASSWORD_FIELD_IS_EMPTY_TITLE"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes); 73 | } 74 | if (success) 75 | { 76 | if (!(tempUsernameCheckBox.Checked)) 77 | { 78 | SAMP.Username = Username; 79 | } 80 | DialogResult = DialogResult.OK; 81 | Close(); 82 | } 83 | } 84 | } 85 | 86 | /// 87 | /// Connect button click event 88 | /// 89 | /// Sender 90 | /// Event arguments 91 | private void connectButton_Click(object sender, EventArgs e) 92 | { 93 | AcceptInput(); 94 | } 95 | 96 | /// 97 | /// Cancel button click event 98 | /// 99 | /// Sender 100 | /// Event arguments 101 | private void cancelButton_Click(object sender, EventArgs e) 102 | { 103 | Close(); 104 | } 105 | 106 | /// 107 | /// Generic single line text field key up event 108 | /// 109 | /// Sender 110 | /// Key event arguments 111 | private void genericSingleLineTextField_KeyUp(object sender, KeyEventArgs e) 112 | { 113 | if (e.KeyCode == Keys.Return) 114 | { 115 | AcceptInput(); 116 | } 117 | else if (e.KeyCode == Keys.Escape) 118 | { 119 | Close(); 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/ConnectHostForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SAMPLauncherNET 2 | { 3 | partial class ConnectHostForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConnectHostForm)); 32 | this.mainFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel(); 33 | this.addressLabel = new MaterialSkin.Controls.MaterialLabel(); 34 | this.hostAndPortSingleLineTextField = new MaterialSkin.Controls.MaterialSingleLineTextField(); 35 | this.connectToAddressButton = new MaterialSkin.Controls.MaterialRaisedButton(); 36 | this.mainFlowLayoutPanel.SuspendLayout(); 37 | this.SuspendLayout(); 38 | // 39 | // mainFlowLayoutPanel 40 | // 41 | this.mainFlowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 42 | | System.Windows.Forms.AnchorStyles.Left) 43 | | System.Windows.Forms.AnchorStyles.Right))); 44 | this.mainFlowLayoutPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51))))); 45 | this.mainFlowLayoutPanel.Controls.Add(this.addressLabel); 46 | this.mainFlowLayoutPanel.Controls.Add(this.hostAndPortSingleLineTextField); 47 | this.mainFlowLayoutPanel.Controls.Add(this.connectToAddressButton); 48 | this.mainFlowLayoutPanel.Location = new System.Drawing.Point(12, 64); 49 | this.mainFlowLayoutPanel.Name = "mainFlowLayoutPanel"; 50 | this.mainFlowLayoutPanel.Size = new System.Drawing.Size(448, 96); 51 | this.mainFlowLayoutPanel.TabIndex = 0; 52 | // 53 | // addressLabel 54 | // 55 | this.addressLabel.Depth = 0; 56 | this.addressLabel.Font = new System.Drawing.Font("Roboto", 11F); 57 | this.addressLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); 58 | this.addressLabel.Location = new System.Drawing.Point(3, 0); 59 | this.addressLabel.MouseState = MaterialSkin.MouseState.HOVER; 60 | this.addressLabel.Name = "addressLabel"; 61 | this.addressLabel.Size = new System.Drawing.Size(445, 23); 62 | this.addressLabel.TabIndex = 2; 63 | this.addressLabel.Text = "{$HOST_AND_PORT$}"; 64 | // 65 | // hostAndPortSingleLineTextField 66 | // 67 | this.hostAndPortSingleLineTextField.Depth = 0; 68 | this.hostAndPortSingleLineTextField.Hint = "..."; 69 | this.hostAndPortSingleLineTextField.Location = new System.Drawing.Point(3, 26); 70 | this.hostAndPortSingleLineTextField.MaxLength = 32767; 71 | this.hostAndPortSingleLineTextField.MouseState = MaterialSkin.MouseState.HOVER; 72 | this.hostAndPortSingleLineTextField.Name = "hostAndPortSingleLineTextField"; 73 | this.hostAndPortSingleLineTextField.PasswordChar = '\0'; 74 | this.hostAndPortSingleLineTextField.SelectedText = ""; 75 | this.hostAndPortSingleLineTextField.SelectionLength = 0; 76 | this.hostAndPortSingleLineTextField.SelectionStart = 0; 77 | this.hostAndPortSingleLineTextField.Size = new System.Drawing.Size(445, 23); 78 | this.hostAndPortSingleLineTextField.TabIndex = 3; 79 | this.hostAndPortSingleLineTextField.TabStop = false; 80 | this.hostAndPortSingleLineTextField.UseSystemPasswordChar = false; 81 | // 82 | // connectToAddressButton 83 | // 84 | this.connectToAddressButton.AutoSize = true; 85 | this.connectToAddressButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 86 | this.connectToAddressButton.Depth = 0; 87 | this.connectToAddressButton.Icon = null; 88 | this.connectToAddressButton.Location = new System.Drawing.Point(3, 55); 89 | this.connectToAddressButton.MouseState = MaterialSkin.MouseState.HOVER; 90 | this.connectToAddressButton.Name = "connectToAddressButton"; 91 | this.connectToAddressButton.Primary = true; 92 | this.connectToAddressButton.Size = new System.Drawing.Size(199, 36); 93 | this.connectToAddressButton.TabIndex = 6; 94 | this.connectToAddressButton.Text = "{$CONNECT_TO_ADDRESS$}"; 95 | this.connectToAddressButton.UseVisualStyleBackColor = true; 96 | this.connectToAddressButton.Click += new System.EventHandler(this.connectToAddressButton_Click); 97 | // 98 | // ConnectHostForm 99 | // 100 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 101 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 102 | this.ClientSize = new System.Drawing.Size(472, 172); 103 | this.Controls.Add(this.mainFlowLayoutPanel); 104 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 105 | this.MaximumSize = new System.Drawing.Size(472, 172); 106 | this.MinimumSize = new System.Drawing.Size(472, 172); 107 | this.Name = "ConnectHostForm"; 108 | this.Sizable = false; 109 | this.Text = "{$CONNECT_TO_ADDRESS_TITLE$}"; 110 | this.mainFlowLayoutPanel.ResumeLayout(false); 111 | this.mainFlowLayoutPanel.PerformLayout(); 112 | this.ResumeLayout(false); 113 | 114 | } 115 | 116 | #endregion 117 | 118 | private System.Windows.Forms.FlowLayoutPanel mainFlowLayoutPanel; 119 | private MaterialSkin.Controls.MaterialLabel addressLabel; 120 | private MaterialSkin.Controls.MaterialSingleLineTextField hostAndPortSingleLineTextField; 121 | private MaterialSkin.Controls.MaterialRaisedButton connectToAddressButton; 122 | } 123 | } -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/ConnectHostForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.Windows.Forms; 4 | using WinFormsTranslator; 5 | 6 | /// 7 | /// SA:MP launcher .NET namespace 8 | /// 9 | namespace SAMPLauncherNET 10 | { 11 | /// 12 | /// Connect host form class 13 | /// 14 | public partial class ConnectHostForm : MaterialForm 15 | { 16 | /// 17 | /// Address 18 | /// 19 | public string HostAndPort 20 | { 21 | get 22 | { 23 | return hostAndPortSingleLineTextField.Text; 24 | } 25 | } 26 | 27 | /// 28 | /// Constructor 29 | /// 30 | public ConnectHostForm(Server server) 31 | { 32 | InitializeComponent(); 33 | Utils.Translator.TranslateControls(this); 34 | if (server != null) 35 | { 36 | hostAndPortSingleLineTextField.Text = server.IPPortString; 37 | } 38 | } 39 | 40 | /// 41 | /// Connect to address click event 42 | /// 43 | /// Sender 44 | /// Event arguments 45 | private void connectToAddressButton_Click(object sender, EventArgs e) 46 | { 47 | DialogResult = DialogResult.OK; 48 | Close(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/DownloadProgressForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SAMPLauncherNET 2 | { 3 | partial class DownloadProgressForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DownloadProgressForm)); 32 | this.mainPanel = new System.Windows.Forms.Panel(); 33 | this.downloadProgressLabel = new MaterialSkin.Controls.MaterialLabel(); 34 | this.downloadProgressBar = new MaterialSkin.Controls.MaterialProgressBar(); 35 | this.mainPanel.SuspendLayout(); 36 | this.SuspendLayout(); 37 | // 38 | // mainPanel 39 | // 40 | this.mainPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 41 | | System.Windows.Forms.AnchorStyles.Left) 42 | | System.Windows.Forms.AnchorStyles.Right))); 43 | this.mainPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51))))); 44 | this.mainPanel.Controls.Add(this.downloadProgressLabel); 45 | this.mainPanel.Controls.Add(this.downloadProgressBar); 46 | this.mainPanel.Location = new System.Drawing.Point(12, 64); 47 | this.mainPanel.Name = "mainPanel"; 48 | this.mainPanel.Size = new System.Drawing.Size(276, 44); 49 | this.mainPanel.TabIndex = 0; 50 | // 51 | // downloadProgressLabel 52 | // 53 | this.downloadProgressLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 54 | | System.Windows.Forms.AnchorStyles.Left) 55 | | System.Windows.Forms.AnchorStyles.Right))); 56 | this.downloadProgressLabel.Depth = 0; 57 | this.downloadProgressLabel.Font = new System.Drawing.Font("Roboto", 11F); 58 | this.downloadProgressLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); 59 | this.downloadProgressLabel.Location = new System.Drawing.Point(3, 0); 60 | this.downloadProgressLabel.MouseState = MaterialSkin.MouseState.HOVER; 61 | this.downloadProgressLabel.Name = "downloadProgressLabel"; 62 | this.downloadProgressLabel.Size = new System.Drawing.Size(270, 33); 63 | this.downloadProgressLabel.TabIndex = 1; 64 | this.downloadProgressLabel.Text = "{$DOWNLOAD_PROGRESS$}"; 65 | this.downloadProgressLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 66 | // 67 | // downloadProgressBar 68 | // 69 | this.downloadProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 70 | | System.Windows.Forms.AnchorStyles.Right))); 71 | this.downloadProgressBar.Depth = 0; 72 | this.downloadProgressBar.Location = new System.Drawing.Point(3, 36); 73 | this.downloadProgressBar.MouseState = MaterialSkin.MouseState.HOVER; 74 | this.downloadProgressBar.Name = "downloadProgressBar"; 75 | this.downloadProgressBar.Size = new System.Drawing.Size(270, 5); 76 | this.downloadProgressBar.TabIndex = 0; 77 | // 78 | // DownloadProgressForm 79 | // 80 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 81 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 82 | this.ClientSize = new System.Drawing.Size(300, 120); 83 | this.Controls.Add(this.mainPanel); 84 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 85 | this.MaximumSize = new System.Drawing.Size(10000, 120); 86 | this.MinimumSize = new System.Drawing.Size(300, 120); 87 | this.Name = "DownloadProgressForm"; 88 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 89 | this.Text = "{$DOWNLOAD_PROGRESS_TITLE$}"; 90 | this.TopMost = true; 91 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.DownloadProgressForm_FormClosing); 92 | this.Load += new System.EventHandler(this.DownloadProgressForm_Load); 93 | this.mainPanel.ResumeLayout(false); 94 | this.ResumeLayout(false); 95 | 96 | } 97 | 98 | #endregion 99 | 100 | private System.Windows.Forms.Panel mainPanel; 101 | private MaterialSkin.Controls.MaterialProgressBar downloadProgressBar; 102 | private MaterialSkin.Controls.MaterialLabel downloadProgressLabel; 103 | } 104 | } -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/DownloadProgressForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.ComponentModel; 4 | using System.IO; 5 | using System.Net; 6 | using System.Windows.Forms; 7 | using WinFormsTranslator; 8 | 9 | /// 10 | /// SA:MP launcher .NET namespace 11 | /// 12 | namespace SAMPLauncherNET 13 | { 14 | /// 15 | /// Download progress form 16 | /// 17 | public partial class DownloadProgressForm : MaterialForm 18 | { 19 | /// 20 | /// URI 21 | /// 22 | private readonly string uri; 23 | 24 | /// 25 | /// Directory 26 | /// 27 | private readonly string directory = ""; 28 | 29 | /// 30 | /// Path 31 | /// 32 | private readonly string path = ""; 33 | 34 | /// 35 | /// Not finished 36 | /// 37 | private bool notFinished = true; 38 | 39 | /// 40 | /// Path 41 | /// 42 | public string Path 43 | { 44 | get 45 | { 46 | return path; 47 | } 48 | } 49 | 50 | /// 51 | /// Constructor 52 | /// 53 | /// URI 54 | /// Path 55 | public DownloadProgressForm(string uri, string path) 56 | { 57 | this.uri = uri; 58 | this.path = path; 59 | directory = System.IO.Path.GetDirectoryName(path); 60 | InitializeComponent(); 61 | Utils.Translator.TranslateControls(this); 62 | } 63 | 64 | /// 65 | /// On download progress changed event 66 | /// 67 | /// Sender 68 | /// Download progress changed event arguments 69 | private void OnDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 70 | { 71 | downloadProgressBar.Maximum = (int)(e.TotalBytesToReceive); 72 | downloadProgressBar.Value = (int)(e.BytesReceived); 73 | TaskbarProgress.SetValue(this, e.BytesReceived, e.TotalBytesToReceive); 74 | } 75 | 76 | /// 77 | /// On download file completed 78 | /// 79 | /// Sender 80 | /// Async completed event arguments 81 | private void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 82 | { 83 | if (e.Error != null) 84 | { 85 | MessageBox.Show(e.Error.Message, Utils.Translator.GetTranslation("DOWNLOAD_FAILED_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 86 | } 87 | else if (!(e.Cancelled)) 88 | { 89 | DialogResult = DialogResult.OK; 90 | } 91 | notFinished = false; 92 | Close(); 93 | } 94 | 95 | /// 96 | /// Download progress form load event 97 | /// 98 | /// Sender 99 | /// Event arguments 100 | private void DownloadProgressForm_Load(object sender, EventArgs e) 101 | { 102 | try 103 | { 104 | if (File.Exists(path)) 105 | { 106 | File.Delete(path); 107 | } 108 | else if (!(Directory.Exists(directory))) 109 | { 110 | Directory.CreateDirectory(directory); 111 | } 112 | WebClient wc = new WebClient(); 113 | wc.Headers.Set(HttpRequestHeader.UserAgent, "Mozilla/3.0 (compatible; SA:MP launcher .NET)"); 114 | wc.DownloadProgressChanged += OnDownloadProgressChanged; 115 | wc.DownloadFileCompleted += OnDownloadFileCompleted; 116 | wc.DownloadFileAsync(new Uri(uri), path); 117 | } 118 | catch (Exception ex) 119 | { 120 | Console.Error.WriteLine(ex); 121 | MessageBox.Show(ex.Message, "Download error", MessageBoxButtons.OK, MessageBoxIcon.Error); 122 | notFinished = false; 123 | Close(); 124 | } 125 | TaskbarProgress.SetState(this, TaskbarProgress.TaskbarStates.Normal); 126 | } 127 | 128 | /// 129 | /// Download progress form form closing event 130 | /// 131 | /// Sender 132 | /// Form closing event arguments 133 | private void DownloadProgressForm_FormClosing(object sender, FormClosingEventArgs e) 134 | { 135 | if (notFinished) 136 | { 137 | if (e.CloseReason == CloseReason.UserClosing) 138 | { 139 | e.Cancel = (MessageBox.Show(Utils.Translator.GetTranslation("CANCEL_DOWNLOAD"), Utils.Translator.GetTranslation("CANCEL_DOWNLOAD_TITLE"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No); 140 | } 141 | } 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/FavouriteListsForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Windows.Forms; 5 | using WinFormsTranslator; 6 | 7 | /// 8 | /// SA:MP launcher .NET namespace 9 | /// 10 | namespace SAMPLauncherNET 11 | { 12 | /// 13 | /// Favourites list form class 14 | /// 15 | public partial class FavouriteListsForm : MaterialForm 16 | { 17 | /// 18 | /// Selected server list connector 19 | /// 20 | public IndexedServerListConnector SelectedServerListConnector 21 | { 22 | get 23 | { 24 | return (IndexedServerListConnector)(favouritesListComboBox.SelectedItem); 25 | } 26 | } 27 | 28 | /// 29 | /// Constructor 30 | /// 31 | /// Favourite lists 32 | public FavouriteListsForm(List favouriteLists) 33 | { 34 | InitializeComponent(); 35 | Utils.Translator.TranslateControls(this); 36 | favouritesListComboBox.Items.AddRange(favouriteLists.ToArray()); 37 | } 38 | 39 | /// 40 | /// OK button click event 41 | /// 42 | /// Sender 43 | /// Event arguments 44 | private void okButton_Click(object sender, EventArgs e) 45 | { 46 | if (SelectedServerListConnector == null) 47 | { 48 | MessageBox.Show(Utils.Translator.GetTranslation("FAVOURITE_LIST_NOT_SELECTED"), Utils.Translator.GetTranslation("FAVOURITE_LIST_NOT_SELECTED_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 49 | } 50 | else 51 | { 52 | DialogResult = DialogResult.OK; 53 | Close(); 54 | } 55 | } 56 | 57 | /// 58 | /// Cancel button click event 59 | /// 60 | /// Sender 61 | /// Event arguments 62 | private void cancelButton_Click(object sender, EventArgs e) 63 | { 64 | Close(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/LoadingForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SAMPLauncherNET 2 | { 3 | partial class LoadingForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LoadingForm)); 32 | this.SuspendLayout(); 33 | // 34 | // LoadingForm 35 | // 36 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 37 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 38 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51))))); 39 | this.ClientSize = new System.Drawing.Size(600, 200); 40 | this.DoubleBuffered = true; 41 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 42 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 43 | this.Name = "LoadingForm"; 44 | this.ShowInTaskbar = false; 45 | this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; 46 | this.TopMost = true; 47 | this.Paint += new System.Windows.Forms.PaintEventHandler(this.LoadingForm_Paint); 48 | this.ResumeLayout(false); 49 | 50 | } 51 | 52 | #endregion 53 | } 54 | } -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/LoadingForm.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Windows.Forms; 3 | using WinFormsTranslator; 4 | 5 | /// 6 | /// SA:MP launcher .NET namespace 7 | /// 8 | namespace SAMPLauncherNET 9 | { 10 | /// 11 | /// Loading form class 12 | /// 13 | public partial class LoadingForm : Form 14 | { 15 | /// 16 | /// Loading text 17 | /// 18 | private string loadingText; 19 | 20 | /// 21 | /// Loading text font 22 | /// 23 | private Font loadingTextFont = new Font("Roboto", 20.25f); 24 | 25 | /// 26 | /// Loading text brush 27 | /// 28 | private Brush loadingTextBrush = Brushes.White; 29 | 30 | /// 31 | /// Loading text point 32 | /// 33 | private Point loadingTextPoint; 34 | 35 | /// 36 | /// Loading text format 37 | /// 38 | StringFormat loadingTextFormat; 39 | 40 | /// 41 | /// Default constructor 42 | /// 43 | public LoadingForm() 44 | { 45 | InitializeComponent(); 46 | //Translator.LoadTranslation(this); 47 | loadingText = Utils.Translator.GetTranslation("LOADING"); 48 | //Size sz = TextRenderer.MeasureText(loadingText, loadingTextFont); 49 | loadingTextPoint = new Point(Size.Width / 2, Size.Height / 2); 50 | loadingTextFormat = new StringFormat(); 51 | loadingTextFormat.LineAlignment = StringAlignment.Center; 52 | loadingTextFormat.Alignment = StringAlignment.Center; 53 | } 54 | 55 | /// 56 | /// Loading form paint event 57 | /// 58 | /// Sender 59 | /// Event arguments 60 | private void LoadingForm_Paint(object sender, PaintEventArgs e) 61 | { 62 | e.Graphics.DrawString(loadingText, loadingTextFont, loadingTextBrush, loadingTextPoint, loadingTextFormat); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/PluginDataForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.Windows.Forms; 4 | using WinFormsTranslator; 5 | 6 | /// 7 | /// SA:MP launcher .NET namespace 8 | /// 9 | namespace SAMPLauncherNET 10 | { 11 | /// 12 | /// Plugin data form 13 | /// 14 | public partial class PluginDataForm : MaterialForm 15 | { 16 | /// 17 | /// Plugin data 18 | /// 19 | public PluginDataContract PluginData 20 | { 21 | get 22 | { 23 | return new PluginDataContract(pluginNameSingleLineTextField.Text, (EPluginProvider)(pluginProviderComboBox.SelectedIndex), pluginURISingleLineTextField.Text, pluginEnabledCheckBox.Checked, (EUpdateFrequency)(pluginUpdateFrequencyComboBox.SelectedIndex)); 24 | } 25 | } 26 | 27 | /// 28 | /// Constructor 29 | /// 30 | /// Plugin data 31 | public PluginDataForm(PluginDataContract pluginData) 32 | { 33 | InitializeComponent(); 34 | Utils.Translator.TranslateControls(this); 35 | Translator.EnumToComboBox(pluginProviderComboBox); 36 | Translator.EnumToComboBox(pluginUpdateFrequencyComboBox); 37 | if (pluginData != null) 38 | { 39 | Text = Utils.Translator.GetTranslation("EDIT_PLUGIN_TITLE"); 40 | pluginEnabledCheckBox.Checked = pluginData.Enabled; 41 | pluginNameSingleLineTextField.Text = pluginData.Name; 42 | pluginProviderComboBox.SelectedIndex = (int)(pluginData.Provider); 43 | pluginURISingleLineTextField.Text = pluginData.URI; 44 | pluginUpdateFrequencyComboBox.SelectedIndex = (int)(pluginData.UpdateFrequency); 45 | } 46 | } 47 | 48 | /// 49 | /// Accept input 50 | /// 51 | private void AcceptInput() 52 | { 53 | if (pluginNameSingleLineTextField.Text.Trim().Length <= 0) 54 | { 55 | MessageBox.Show(Utils.Translator.GetTranslation("PLUGIN_NAME_MISSING"), Utils.Translator.GetTranslation("PLUGIN_NAME_MISSING_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 56 | } 57 | else 58 | { 59 | if (pluginProviderComboBox.SelectedIndex < 0) 60 | { 61 | MessageBox.Show(Utils.Translator.GetTranslation("PLUGIN_PROVIDER_MISSING"), Utils.Translator.GetTranslation("PLUGIN_PROVIDER_MISSING_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 62 | } 63 | else 64 | { 65 | if (pluginURISingleLineTextField.Text.Trim().Length <= 0) 66 | { 67 | MessageBox.Show(Utils.Translator.GetTranslation("PLUGIN_URI_MISSING"), Utils.Translator.GetTranslation("PLUGIN_URI_MISSING_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 68 | } 69 | else 70 | { 71 | if (pluginUpdateFrequencyComboBox.SelectedIndex < 0) 72 | { 73 | MessageBox.Show(Utils.Translator.GetTranslation("PLUGIN_UPDATE_FREQUENCY_MISSING"), Utils.Translator.GetTranslation("PLUGIN_UPDATE_FREQUENCY_MISSING_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); 74 | } 75 | else 76 | { 77 | DialogResult = DialogResult.OK; 78 | Close(); 79 | } 80 | } 81 | } 82 | } 83 | } 84 | 85 | /// 86 | /// Plugin generic single line text field key up event 87 | /// 88 | /// Sender 89 | /// Key event arguments 90 | private void pluginGenericSingleLineTextField_KeyUp(object sender, KeyEventArgs e) 91 | { 92 | if (e.KeyCode == Keys.Return) 93 | { 94 | AcceptInput(); 95 | } 96 | else if (e.KeyCode == Keys.Escape) 97 | { 98 | Close(); 99 | } 100 | } 101 | 102 | /// 103 | /// OK button click event 104 | /// 105 | /// Sender 106 | /// Event arguments 107 | private void okButton_Click(object sender, EventArgs e) 108 | { 109 | AcceptInput(); 110 | } 111 | 112 | /// 113 | /// Cancel button click event 114 | /// 115 | /// Sender 116 | /// Event arguments 117 | private void cancelButton_Click(object sender, EventArgs e) 118 | { 119 | Close(); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/RCONPasswordForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using System; 3 | using System.Windows.Forms; 4 | using WinFormsTranslator; 5 | 6 | /// 7 | /// SA:MP launcher .NET namespace 8 | /// 9 | namespace SAMPLauncherNET 10 | { 11 | /// 12 | /// RCON password form class 13 | /// 14 | public partial class RCONPasswordForm : MaterialForm 15 | { 16 | /// 17 | /// RCON password 18 | /// 19 | public string RCONPassword 20 | { 21 | get 22 | { 23 | return rconPasswordTextBox.Text; 24 | } 25 | } 26 | 27 | /// 28 | /// Deefault constructor 29 | /// 30 | public RCONPasswordForm() 31 | { 32 | InitializeComponent(); 33 | Utils.Translator.TranslateControls(this); 34 | } 35 | 36 | /// 37 | /// Connect button click event 38 | /// 39 | /// Sender 40 | /// Event arguments 41 | private void connectButton_Click(object sender, EventArgs e) 42 | { 43 | DialogResult = DialogResult.OK; 44 | Close(); 45 | } 46 | 47 | /// 48 | /// Cancel button click event 49 | /// 50 | /// Sender 51 | /// Event arguments 52 | private void cancelButton_Click(object sender, EventArgs e) 53 | { 54 | Close(); 55 | } 56 | 57 | /// 58 | /// RCON password text box key up event 59 | /// 60 | /// Sender 61 | /// Key event arguments 62 | private void rconPasswordTextBox_KeyUp(object sender, KeyEventArgs e) 63 | { 64 | if (e.KeyCode == Keys.Return) 65 | { 66 | DialogResult = DialogResult.OK; 67 | Close(); 68 | } 69 | else if (e.KeyCode == Keys.Escape) 70 | { 71 | Close(); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/SessionForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SAMPLauncherNET 2 | { 3 | partial class SessionForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SessionForm)); 32 | this.mainTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); 33 | this.buttonsFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel(); 34 | this.deleteButton = new MaterialSkin.Controls.MaterialRaisedButton(); 35 | this.okButton = new MaterialSkin.Controls.MaterialRaisedButton(); 36 | this.mainTableLayoutPanel.SuspendLayout(); 37 | this.buttonsFlowLayoutPanel.SuspendLayout(); 38 | this.SuspendLayout(); 39 | // 40 | // mainTableLayoutPanel 41 | // 42 | this.mainTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 43 | | System.Windows.Forms.AnchorStyles.Left) 44 | | System.Windows.Forms.AnchorStyles.Right))); 45 | this.mainTableLayoutPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51))))); 46 | this.mainTableLayoutPanel.ColumnCount = 1; 47 | this.mainTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); 48 | this.mainTableLayoutPanel.Controls.Add(this.buttonsFlowLayoutPanel, 0, 1); 49 | this.mainTableLayoutPanel.Location = new System.Drawing.Point(12, 64); 50 | this.mainTableLayoutPanel.Name = "mainTableLayoutPanel"; 51 | this.mainTableLayoutPanel.RowCount = 2; 52 | this.mainTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); 53 | this.mainTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 44F)); 54 | this.mainTableLayoutPanel.Size = new System.Drawing.Size(976, 674); 55 | this.mainTableLayoutPanel.TabIndex = 0; 56 | // 57 | // buttonsFlowLayoutPanel 58 | // 59 | this.buttonsFlowLayoutPanel.Controls.Add(this.deleteButton); 60 | this.buttonsFlowLayoutPanel.Controls.Add(this.okButton); 61 | this.buttonsFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; 62 | this.buttonsFlowLayoutPanel.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; 63 | this.buttonsFlowLayoutPanel.Location = new System.Drawing.Point(3, 633); 64 | this.buttonsFlowLayoutPanel.Name = "buttonsFlowLayoutPanel"; 65 | this.buttonsFlowLayoutPanel.Size = new System.Drawing.Size(970, 38); 66 | this.buttonsFlowLayoutPanel.TabIndex = 0; 67 | // 68 | // deleteButton 69 | // 70 | this.deleteButton.AutoSize = true; 71 | this.deleteButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 72 | this.deleteButton.Depth = 0; 73 | this.deleteButton.Icon = null; 74 | this.deleteButton.Location = new System.Drawing.Point(873, 3); 75 | this.deleteButton.MouseState = MaterialSkin.MouseState.HOVER; 76 | this.deleteButton.Name = "deleteButton"; 77 | this.deleteButton.Primary = true; 78 | this.deleteButton.Size = new System.Drawing.Size(94, 36); 79 | this.deleteButton.TabIndex = 1; 80 | this.deleteButton.Text = "{$DELETE$}"; 81 | this.deleteButton.UseVisualStyleBackColor = true; 82 | this.deleteButton.Click += new System.EventHandler(this.deleteButton_Click); 83 | // 84 | // okButton 85 | // 86 | this.okButton.AutoSize = true; 87 | this.okButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 88 | this.okButton.Depth = 0; 89 | this.okButton.Icon = null; 90 | this.okButton.Location = new System.Drawing.Point(803, 3); 91 | this.okButton.MouseState = MaterialSkin.MouseState.HOVER; 92 | this.okButton.Name = "okButton"; 93 | this.okButton.Primary = true; 94 | this.okButton.Size = new System.Drawing.Size(64, 36); 95 | this.okButton.TabIndex = 0; 96 | this.okButton.Text = "{$OK$}"; 97 | this.okButton.UseVisualStyleBackColor = true; 98 | this.okButton.Click += new System.EventHandler(this.okButton_Click); 99 | // 100 | // SessionForm 101 | // 102 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 103 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 104 | this.ClientSize = new System.Drawing.Size(1000, 750); 105 | this.Controls.Add(this.mainTableLayoutPanel); 106 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 107 | this.Name = "SessionForm"; 108 | this.Text = "{$SESSION$}"; 109 | this.TopMost = true; 110 | this.mainTableLayoutPanel.ResumeLayout(false); 111 | this.buttonsFlowLayoutPanel.ResumeLayout(false); 112 | this.buttonsFlowLayoutPanel.PerformLayout(); 113 | this.ResumeLayout(false); 114 | 115 | } 116 | 117 | #endregion 118 | 119 | private System.Windows.Forms.TableLayoutPanel mainTableLayoutPanel; 120 | private System.Windows.Forms.FlowLayoutPanel buttonsFlowLayoutPanel; 121 | private MaterialSkin.Controls.MaterialRaisedButton okButton; 122 | private MaterialSkin.Controls.MaterialRaisedButton deleteButton; 123 | } 124 | } -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/SessionForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin.Controls; 2 | using SAMPLauncherNET.UI; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.Windows.Forms; 7 | using WinFormsTranslator; 8 | 9 | /// 10 | /// SA:MP launcher .NET namespace 11 | /// 12 | namespace SAMPLauncherNET 13 | { 14 | /// 15 | /// Session form class 16 | /// 17 | public partial class SessionForm : MaterialForm 18 | { 19 | /// 20 | /// Session 21 | /// 22 | private Session session; 23 | 24 | /// 25 | /// Gallery 26 | /// 27 | private Dictionary loadedGallery = new Dictionary(); 28 | 29 | /// 30 | /// Constructor 31 | /// 32 | /// Session 33 | public SessionForm(Session session) 34 | { 35 | this.session = session; 36 | InitializeComponent(); 37 | Utils.Translator.TranslateControls(this); 38 | SessionUserControl suc = new SessionUserControl(session); 39 | mainTableLayoutPanel.Controls.Add(suc, 0, 0); 40 | suc.Dock = DockStyle.Fill; 41 | } 42 | 43 | /// 44 | /// OK button click 45 | /// 46 | /// Sender 47 | /// Event arguments 48 | private void okButton_Click(object sender, EventArgs e) 49 | { 50 | DialogResult = DialogResult.OK; 51 | Close(); 52 | } 53 | 54 | /// 55 | /// Delete button click 56 | /// 57 | /// Sender 58 | /// Event arguments 59 | private void deleteButton_Click(object sender, EventArgs e) 60 | { 61 | DialogResult result = MessageBox.Show(Utils.Translator.GetTranslation("SESSION_DELETE"), Utils.Translator.GetTranslation("SESSION_DELETE_TITLE"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning); 62 | DialogResult = DialogResult.None; 63 | if (result == DialogResult.Yes) 64 | { 65 | DialogResult = DialogResult.No; 66 | Close(); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/UpdateNotificationForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SAMPLauncherNET 2 | { 3 | partial class UpdateNotificationForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdateNotificationForm)); 32 | this.mainFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel(); 33 | this.updateNotificationLabel = new MaterialSkin.Controls.MaterialLabel(); 34 | this.yesButton = new MaterialSkin.Controls.MaterialRaisedButton(); 35 | this.noButton = new MaterialSkin.Controls.MaterialRaisedButton(); 36 | this.mainFlowLayoutPanel.SuspendLayout(); 37 | this.SuspendLayout(); 38 | // 39 | // mainFlowLayoutPanel 40 | // 41 | this.mainFlowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 42 | | System.Windows.Forms.AnchorStyles.Left) 43 | | System.Windows.Forms.AnchorStyles.Right))); 44 | this.mainFlowLayoutPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51))))); 45 | this.mainFlowLayoutPanel.Controls.Add(this.updateNotificationLabel); 46 | this.mainFlowLayoutPanel.Controls.Add(this.yesButton); 47 | this.mainFlowLayoutPanel.Controls.Add(this.noButton); 48 | this.mainFlowLayoutPanel.Location = new System.Drawing.Point(5, 64); 49 | this.mainFlowLayoutPanel.Name = "mainFlowLayoutPanel"; 50 | this.mainFlowLayoutPanel.Size = new System.Drawing.Size(390, 119); 51 | this.mainFlowLayoutPanel.TabIndex = 1; 52 | // 53 | // updateNotificationLabel 54 | // 55 | this.updateNotificationLabel.AutoSize = true; 56 | this.updateNotificationLabel.Depth = 0; 57 | this.updateNotificationLabel.Font = new System.Drawing.Font("Roboto", 11F); 58 | this.updateNotificationLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); 59 | this.updateNotificationLabel.Location = new System.Drawing.Point(3, 0); 60 | this.updateNotificationLabel.MouseState = MaterialSkin.MouseState.HOVER; 61 | this.updateNotificationLabel.Name = "updateNotificationLabel"; 62 | this.updateNotificationLabel.Size = new System.Drawing.Size(199, 19); 63 | this.updateNotificationLabel.TabIndex = 13; 64 | this.updateNotificationLabel.Text = "{$UPDATE_NOTIFICATION$}"; 65 | // 66 | // yesButton 67 | // 68 | this.yesButton.AutoSize = true; 69 | this.yesButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 70 | this.yesButton.Depth = 0; 71 | this.yesButton.Icon = null; 72 | this.yesButton.Location = new System.Drawing.Point(208, 3); 73 | this.yesButton.MouseState = MaterialSkin.MouseState.HOVER; 74 | this.yesButton.Name = "yesButton"; 75 | this.yesButton.Primary = true; 76 | this.yesButton.Size = new System.Drawing.Size(70, 36); 77 | this.yesButton.TabIndex = 11; 78 | this.yesButton.Text = "{$YES$}"; 79 | this.yesButton.UseVisualStyleBackColor = true; 80 | this.yesButton.Click += new System.EventHandler(this.yesButton_Click); 81 | // 82 | // noButton 83 | // 84 | this.noButton.AutoSize = true; 85 | this.noButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 86 | this.noButton.Depth = 0; 87 | this.noButton.Icon = null; 88 | this.noButton.Location = new System.Drawing.Point(284, 3); 89 | this.noButton.MouseState = MaterialSkin.MouseState.HOVER; 90 | this.noButton.Name = "noButton"; 91 | this.noButton.Primary = true; 92 | this.noButton.Size = new System.Drawing.Size(65, 36); 93 | this.noButton.TabIndex = 12; 94 | this.noButton.Text = "{$NO$}"; 95 | this.noButton.UseVisualStyleBackColor = true; 96 | this.noButton.Click += new System.EventHandler(this.noButton_Click); 97 | // 98 | // UpdateNotificationForm 99 | // 100 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 101 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 102 | this.ClientSize = new System.Drawing.Size(400, 195); 103 | this.Controls.Add(this.mainFlowLayoutPanel); 104 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 105 | this.Name = "UpdateNotificationForm"; 106 | this.Text = "{$UPDATE_NOTIFICATION_TITLE$}"; 107 | this.mainFlowLayoutPanel.ResumeLayout(false); 108 | this.mainFlowLayoutPanel.PerformLayout(); 109 | this.ResumeLayout(false); 110 | 111 | } 112 | 113 | #endregion 114 | 115 | private System.Windows.Forms.FlowLayoutPanel mainFlowLayoutPanel; 116 | private MaterialSkin.Controls.MaterialRaisedButton yesButton; 117 | private MaterialSkin.Controls.MaterialRaisedButton noButton; 118 | private MaterialSkin.Controls.MaterialLabel updateNotificationLabel; 119 | } 120 | } -------------------------------------------------------------------------------- /SAMPLauncherNET/Source/SAMPLauncherNET/UI/Forms/UpdateNotificationForm.cs: -------------------------------------------------------------------------------- 1 | using MaterialSkin; 2 | using MaterialSkin.Controls; 3 | using System; 4 | using System.Windows.Forms; 5 | 6 | /// 7 | /// SAMP Launcher .NET namespace 8 | /// 9 | namespace SAMPLauncherNET 10 | { 11 | /// 12 | /// Update notification form 13 | /// 14 | public partial class UpdateNotificationForm : MaterialForm 15 | { 16 | /// 17 | /// Default constructor 18 | /// 19 | public UpdateNotificationForm(string version) 20 | { 21 | InitializeComponent(); 22 | Utils.Translator.TranslateControls(this); 23 | MaterialSkinManager material_skin_manager = MaterialSkinManager.Instance; 24 | material_skin_manager.AddFormToManage(this); 25 | material_skin_manager.Theme = MaterialSkinManager.Themes.DARK; 26 | material_skin_manager.ColorScheme = new ColorScheme(Primary.Blue700, Primary.Blue800, Primary.Blue500, Accent.LightBlue200, TextShade.WHITE); 27 | string update_notification; 28 | if (Utils.Translator.TryTranslate("{$UPDATE_NOTIFICATION$}", out update_notification)) 29 | { 30 | updateNotificationLabel.Text = string.Format(update_notification, version); 31 | } 32 | } 33 | 34 | /// 35 | /// Yes button click event 36 | /// 37 | /// Sender 38 | /// Event arguments 39 | private void yesButton_Click(object sender, EventArgs e) 40 | { 41 | DialogResult = DialogResult.Yes; 42 | Close(); 43 | } 44 | 45 | /// 46 | /// No button click event 47 | /// 48 | /// Sender 49 | /// Event arguments 50 | private void noButton_Click(object sender, EventArgs e) 51 | { 52 | DialogResult = DialogResult.No; 53 | Close(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SAMPLauncherNET/libs/INIEngine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/libs/INIEngine.dll -------------------------------------------------------------------------------- /SAMPLauncherNET/libs/MaterialSkin.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/libs/MaterialSkin.dll -------------------------------------------------------------------------------- /SAMPLauncherNET/libs/Ude.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/libs/Ude.dll -------------------------------------------------------------------------------- /SAMPLauncherNET/libs/WinFormsTranslator.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/libs/WinFormsTranslator.dll -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 3e2621996f6da2a9f623857c8b452008b1dbf111 2 | -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/TempPE/Languages.de-DE.Designer.cs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/TempPE/Languages.de-DE.Designer.cs.dll -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/TempPE/Languages.en-GB.Designer.cs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/TempPE/Languages.en-GB.Designer.cs.dll -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /SAMPLauncherNET/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /SAMPLauncherNET/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /SAMPLauncherNET/samp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/SAMPLauncherNET/samp.ico -------------------------------------------------------------------------------- /api.json: -------------------------------------------------------------------------------- 1 | [{"endpoint":"https:\/\/api.samp-servers.net\/v2\/servers","name":"{$SHOW_SOUTHCLAWS_LIST$}","type":"BackendRESTful"},{"endpoint":"http:\/\/monitor.sacnr.com\/list\/masterlist.txt","name":"{$SHOW_SACNR_LIST$}","type":"LegacySAMP"}] -------------------------------------------------------------------------------- /libs/MaterialSkin.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/libs/MaterialSkin.dll -------------------------------------------------------------------------------- /libs/UpdaterNET.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/libs/UpdaterNET.dll -------------------------------------------------------------------------------- /plugins.json: -------------------------------------------------------------------------------- 1 | [{"enabled":false,"name":"SA:MP Discord Rich Presence plugin","provider":"GitHub","updateFrequency":"WhenNewer","uri":"https:\/\/github.com\/Hual\/samp-discord-plugin"}] -------------------------------------------------------------------------------- /screenshots/screenshot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot001.png -------------------------------------------------------------------------------- /screenshots/screenshot002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot002.png -------------------------------------------------------------------------------- /screenshots/screenshot003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot003.png -------------------------------------------------------------------------------- /screenshots/screenshot004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot004.png -------------------------------------------------------------------------------- /screenshots/screenshot005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot005.png -------------------------------------------------------------------------------- /screenshots/screenshot006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot006.png -------------------------------------------------------------------------------- /screenshots/screenshot007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot007.png -------------------------------------------------------------------------------- /screenshots/screenshot008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot008.png -------------------------------------------------------------------------------- /screenshots/screenshot009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot009.png -------------------------------------------------------------------------------- /screenshots/screenshot010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot010.png -------------------------------------------------------------------------------- /screenshots/screenshot011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot011.png -------------------------------------------------------------------------------- /screenshots/screenshot012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot012.png -------------------------------------------------------------------------------- /screenshots/screenshot013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot013.png -------------------------------------------------------------------------------- /screenshots/screenshot014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot014.png -------------------------------------------------------------------------------- /screenshots/screenshot015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot015.png -------------------------------------------------------------------------------- /screenshots/screenshot016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot016.png -------------------------------------------------------------------------------- /screenshots/screenshot017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot017.png -------------------------------------------------------------------------------- /screenshots/screenshot018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot018.png -------------------------------------------------------------------------------- /screenshots/screenshot019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigETI/SAMPLauncherNET/a7412785ff339d844ed7586cb0dbd1e237fdffc8/screenshots/screenshot019.png -------------------------------------------------------------------------------- /update.json: -------------------------------------------------------------------------------- 1 | {"sha512":"rD1qVa35DTYKzdwJi9P4vYslndCpC\/VI3b8YHla13jj5iTQanADnCi8uib1TaimvsXVZao3wdj6wa7nfsevQmw==","uri":"https:\/\/github.com\/BigETI\/SAMPLauncherNET\/releases\/download\/v1.0.6.0\/SAMPLauncherNET-1.0.6.0.zip","version":"1.0.6.0","version_number":1000600} --------------------------------------------------------------------------------