diff --git a/.gitignore b/.gitignore
index fc70947..104105f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -211,3 +211,6 @@ GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
*.csproj
+*.csproj
+*.csproj
+gtaserver.core/serverSettings.xml
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..74eac52
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "lidgren.network"]
+ path = lidgren.network
+ url = https://gitlab.com/TinyMP/LidgrenNetwork.git
diff --git a/.pullapprove.yml b/.pullapprove.yml
new file mode 100644
index 0000000..c91b484
--- /dev/null
+++ b/.pullapprove.yml
@@ -0,0 +1,9 @@
+approve_by_comment: true
+approve_regex: ^Approved
+reject_regex: ^Rejected
+reset_on_push: false
+reviewers:
+ members:
+ - Bluscream
+ name: pullapprove
+ required: 1
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..8b7ea6b
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,6 @@
+language: csharp
+solution: GTACoOp.sln
+os: windows
+branches:
+ only:
+ - indev-server
diff --git a/AdminTools/AdminSettings.cs b/AdminTools/AdminSettings.cs
new file mode 100644
index 0000000..4a2512d
--- /dev/null
+++ b/AdminTools/AdminSettings.cs
@@ -0,0 +1,57 @@
+namespace AdminTools
+{
+ public class AdminSettings
+ {
+ public bool Debug { get; set; }
+ public bool KickOnDefaultNickName { get; set; }
+ public bool KickOnNameDifference { get; set; }
+ public bool SocialClubOnly { get; set; }
+ public string MOTD { get; set; }
+ public int MaxPing { get; set; }
+ public bool AntiClones { get; set; }
+ public bool KickOnDifferentScript { get; set; }
+ public GTAServer.ScriptVersion NeededScriptVersion { get; set; }
+ public bool KickOnOutdatedGame { get; set; }
+ public int MinGameVersion { get; set; }
+ public bool ColoredNicknames { get; set; }
+ public bool OnlyAsciiNickName { get; set; }
+ public bool OnlyAsciiUserName { get; set; }
+ public bool LimitNickNames { get; set; }
+ public string CountryRestriction { get; set; }
+ public string ProtectedNickname { get; set; }
+ public string ProtectedNicknameIP { get; set; }
+
+ /*public bool WhiteListEnabled { get; set; }
+public string[] WhiteList { get; set; }
+public bool BlackListEnabled { get; set; }
+public string[] BlackList { get; set; }*/
+
+ public AdminSettings()
+ {
+ Debug = false;
+ KickOnDefaultNickName = true;
+ KickOnNameDifference = false;
+ SocialClubOnly = false;
+ MOTD = "Welcome to this GTA 5 Co-op Server! Max Ping: 250";
+ MaxPing = 250;
+ AntiClones = true;
+ KickOnDifferentScript = true;
+ NeededScriptVersion = GTAServer.ScriptVersion.VERSION_0_9_3;
+ KickOnOutdatedGame = false;
+ MinGameVersion = 25;
+ ColoredNicknames = true;
+ OnlyAsciiNickName = true;
+ OnlyAsciiUserName = false;
+ LimitNickNames = true;
+ CountryRestriction = "";
+ ProtectedNickname = "";
+ ProtectedNicknameIP = "";
+ /*WhiteListEnabled = false;
+ WhiteList[0] = "Bluscream";
+ WhiteList[1] = "Redscream";
+ BlackListEnabled = false;
+ BlackList[0] = "Faggot";
+ BlackList[1] = "Bastard";*/
+ }
+ }
+}
\ No newline at end of file
diff --git a/AdminTools/AdminTools.csproj b/AdminTools/AdminTools.csproj
index e53c355..ceee3db 100644
--- a/AdminTools/AdminTools.csproj
+++ b/AdminTools/AdminTools.csproj
@@ -25,7 +25,7 @@
pdbonly
true
- bin\Release\
+ ..\..\..\..\SERVERS\GameServer\Grand Theft Auto\GTA V\filterscripts\
TRACE
prompt
4
@@ -38,15 +38,26 @@
-
- ..\libs\Lidgren.Network.dll
+
+ ..\packages\Lidgren.Network.1.0.2\lib\net451\Lidgren.Network.dll
+ True
-
- False
- ..\libs\Newtonsoft.Json.dll
+
+ ..\packages\MaxMind.Db.2.0.0\lib\net45\MaxMind.Db.dll
+ True
+
+
+ ..\packages\MaxMind.GeoIP2.2.6.0\lib\net45\MaxMind.GeoIP2.dll
+ True
+
+
+ ..\packages\protobuf-net.2.1.0\lib\net451\protobuf-net.dll
+ True
+
+
@@ -55,13 +66,15 @@
+
-
- True
- True
- Settings.settings
-
+
+
+
+ Designer
+
+
@@ -69,13 +82,6 @@
GTAServer
-
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
+
+
+ FileSystem
+ Debug
+ Any CPU
+
+ True
+ False
+ netstandard1.6
+ osx.10.10-x64
+ True
+ publish\ubuntu.14.04-x64-debug
+ True
+
+
\ No newline at end of file
diff --git a/gtaserver.core/Properties/PublishProfiles/publish-module.psm1 b/gtaserver.core/Properties/PublishProfiles/publish-module.psm1
new file mode 100644
index 0000000..adc6ada
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/publish-module.psm1
@@ -0,0 +1,1231 @@
+# WARNING: DO NOT MODIFY this file. Visual Studio will override it.
+param()
+
+$script:AspNetPublishHandlers = @{}
+
+<#
+These settings can be overridden with environment variables.
+The name of the environment variable should use "Publish" as a
+prefix and the names below. For example:
+
+ $env:PublishMSDeployUseChecksum = $true
+#>
+$global:AspNetPublishSettings = New-Object -TypeName PSCustomObject @{
+ MsdeployDefaultProperties = @{
+ 'MSDeployUseChecksum'=$false
+ 'SkipExtraFilesOnServer'=$true
+ 'retryAttempts' = 20
+ 'EnableMSDeployBackup' = $false
+ 'DeleteExistingFiles' = $false
+ 'AllowUntrustedCertificate'= $false
+ 'MSDeployPackageContentFoldername'='website\'
+ 'EnvironmentName' = 'Production'
+ 'AuthType'='Basic'
+ 'MSDeployPublishMethod'='WMSVC'
+ }
+}
+
+function InternalOverrideSettingsFromEnv{
+ [cmdletbinding()]
+ param(
+ [Parameter(Position=0)]
+ [object[]]$settings = ($global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties),
+
+ [Parameter(Position=1)]
+ [string]$prefix = 'Publish'
+ )
+ process{
+ foreach($settingsObj in $settings){
+ if($settingsObj -eq $null){
+ continue
+ }
+
+ $settingNames = $null
+ if($settingsObj -is [hashtable]){
+ $settingNames = $settingsObj.Keys
+ }
+ else{
+ $settingNames = ($settingsObj | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name)
+
+ }
+
+ foreach($name in @($settingNames)){
+ $fullname = ('{0}{1}' -f $prefix,$name)
+ if(Test-Path "env:$fullname"){
+ $settingsObj.$name = ((get-childitem "env:$fullname").Value)
+ }
+ }
+ }
+ }
+}
+
+InternalOverrideSettingsFromEnv -prefix 'Publish' -settings $global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties
+
+function Register-AspnetPublishHandler{
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true,Position=0)]
+ $name,
+ [Parameter(Mandatory=$true,Position=1)]
+ [ScriptBlock]$handler,
+ [switch]$force
+ )
+ process{
+ if(!($script:AspNetPublishHandlers[$name]) -or $force ){
+ 'Adding handler for [{0}]' -f $name | Write-Verbose
+ $script:AspNetPublishHandlers[$name] = $handler
+ }
+ elseif(!($force)){
+ 'Ignoring call to Register-AspnetPublishHandler for [name={0}], because a handler with that name exists and -force was not passed.' -f $name | Write-Verbose
+ }
+ }
+}
+
+function Get-AspnetPublishHandler{
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true,Position=0)]
+ $name
+ )
+ process{
+ $foundHandler = $script:AspNetPublishHandlers[$name]
+
+ if(!$foundHandler){
+ throw ('AspnetPublishHandler with name "{0}" was not found' -f $name)
+ }
+
+ $foundHandler
+ }
+}
+
+function GetInternal-ExcludeFilesArg{
+ [cmdletbinding()]
+ param(
+ $publishProperties
+ )
+ process{
+ $excludeFiles = $publishProperties['ExcludeFiles']
+ foreach($exclude in $excludeFiles){
+ if($exclude){
+ [string]$objName = $exclude['objectname']
+
+ if([string]::IsNullOrEmpty($objName)){
+ $objName = 'filePath'
+ }
+
+ $excludePath = $exclude['absolutepath']
+
+ # output the result to the return list
+ ('-skip:objectName={0},absolutePath=''{1}''' -f $objName, $excludePath)
+ }
+ }
+ }
+}
+
+function GetInternal-ReplacementsMSDeployArgs{
+ [cmdletbinding()]
+ param(
+ $publishProperties
+ )
+ process{
+ foreach($replace in ($publishProperties['Replacements'])){
+ if($replace){
+ $typeValue = $replace['type']
+ if(!$typeValue){ $typeValue = 'TextFile' }
+
+ $file = $replace['file']
+ $match = $replace['match']
+ $newValue = $replace['newValue']
+
+ if($file -and $match -and $newValue){
+ $setParam = ('-setParam:type={0},scope={1},match={2},value={3}' -f $typeValue,$file, $match,$newValue)
+ 'Adding setparam [{0}]' -f $setParam | Write-Verbose
+
+ # return it
+ $setParam
+ }
+ else{
+ 'Skipping replacement because its missing a required value.[file="{0}",match="{1}",newValue="{2}"]' -f $file,$match,$newValue | Write-Verbose
+ }
+ }
+ }
+ }
+}
+
+<#
+.SYNOPSIS
+Returns an array of msdeploy arguments that are used across different providers.
+For example this will handle useChecksum, AppOffline etc.
+This will also add default properties if they are missing.
+#>
+function GetInternal-SharedMSDeployParametersFrom{
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true,Position=0)]
+ [HashTable]$publishProperties,
+ [Parameter(Mandatory=$true,Position=1)]
+ [System.IO.FileInfo]$packOutput
+ )
+ process{
+ $sharedArgs = New-Object psobject -Property @{
+ ExtraArgs = @()
+ DestFragment = ''
+ EFMigrationData = @{}
+ }
+
+ # add default properties if they are missing
+ foreach($propName in $global:AspNetPublishSettings.MsdeployDefaultProperties.Keys){
+ if($publishProperties["$propName"] -eq $null){
+ $defValue = $global:AspNetPublishSettings.MsdeployDefaultProperties["$propName"]
+ 'Adding default property to publishProperties ["{0}"="{1}"]' -f $propName,$defValue | Write-Verbose
+ $publishProperties["$propName"] = $defValue
+ }
+ }
+
+ if($publishProperties['MSDeployUseChecksum'] -eq $true){
+ $sharedArgs.ExtraArgs += '-usechecksum'
+ }
+
+ if($publishProperties['EnableMSDeployAppOffline'] -eq $true){
+ $sharedArgs.ExtraArgs += '-enablerule:AppOffline'
+ }
+
+ if($publishProperties['WebPublishMethod'] -eq 'MSDeploy'){
+ if($publishProperties['SkipExtraFilesOnServer'] -eq $true){
+ $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule'
+ }
+ }
+
+ if($publishProperties['WebPublishMethod'] -eq 'FileSystem'){
+ if($publishProperties['DeleteExistingFiles'] -eq $false){
+ $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule'
+ }
+ }
+
+ if($publishProperties['retryAttempts']){
+ $sharedArgs.ExtraArgs += ('-retryAttempts:{0}' -f ([int]$publishProperties['retryAttempts']))
+ }
+
+ if($publishProperties['EncryptWebConfig'] -eq $true){
+ $sharedArgs.ExtraArgs += '-EnableRule:EncryptWebConfig'
+ }
+
+ if($publishProperties['EnableMSDeployBackup'] -eq $false){
+ $sharedArgs.ExtraArgs += '-disablerule:BackupRule'
+ }
+
+ if($publishProperties['AllowUntrustedCertificate'] -eq $true){
+ $sharedArgs.ExtraArgs += '-allowUntrusted'
+ }
+
+ # add excludes
+ $sharedArgs.ExtraArgs += (GetInternal-ExcludeFilesArg -publishProperties $publishProperties)
+ # add replacements
+ $sharedArgs.ExtraArgs += (GetInternal-ReplacementsMSDeployArgs -publishProperties $publishProperties)
+
+ # add EF Migration
+ if (($publishProperties['EfMigrations'] -ne $null) -and $publishProperties['EfMigrations'].Count -gt 0){
+ if (!(Test-Path -Path $publishProperties['ProjectPath'])) {
+ throw 'ProjectPath property needs to be defined in the pubxml for EF migration.'
+ }
+ try {
+ # generate T-SQL files
+ $EFSqlFiles = GenerateInternal-EFMigrationScripts -projectPath $publishProperties['ProjectPath'] -packOutput $packOutput -EFMigrations $publishProperties['EfMigrations']
+ $sharedArgs.EFMigrationData.Add('EFSqlFiles',$EFSqlFiles)
+ }
+ catch {
+ throw ('An error occurred while generating EF migrations. {0} {1}' -f $_.Exception,(Get-PSCallStack))
+ }
+ }
+ # add connection string update
+ if (($publishProperties['DestinationConnectionStrings'] -ne $null) -and $publishProperties['DestinationConnectionStrings'].Count -gt 0) {
+ try {
+ # create/update appsettings.[environment].json
+ GenerateInternal-AppSettingsFile -packOutput $packOutput -environmentName $publishProperties['EnvironmentName'] -connectionStrings $publishProperties['DestinationConnectionStrings']
+ }
+ catch {
+ throw ('An error occurred while generating the publish appsettings file. {0} {1}' -f $_.Exception,(Get-PSCallStack))
+ }
+ }
+
+ if(-not [string]::IsNullOrWhiteSpace($publishProperties['ProjectGuid'])) {
+ AddInternal-ProjectGuidToWebConfig -publishProperties $publishProperties -packOutput $packOutput
+ }
+
+ # return the args
+ $sharedArgs
+ }
+}
+
+<#
+.SYNOPSIS
+This will publish the folder based on the properties in $publishProperties
+
+.PARAMETER publishProperties
+This is a hashtable containing the publish properties. See the examples here for more info on how to use this parameter.
+
+.PARAMETER packOutput
+The folder path to the output of the dnu publish command. This folder contains the files
+that will be published.
+
+.PARAMETER pubProfilePath
+Path to a publish profile (.pubxml file) to import publish properties from. If the same property exists in
+publishProperties and the publish profile then publishProperties will win.
+
+.EXAMPLE
+ Publish-AspNet -packOutput $packOutput -publishProperties @{
+ 'WebPublishMethod'='MSDeploy'
+ 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';`
+ 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="$env:PublishPwd"}
+
+.EXAMPLE
+Publish-AspNet -packOutput $packOutput -publishProperties @{
+ 'WebPublishMethod'='FileSystem'
+ 'publishUrl'="$publishDest"
+ }
+
+.EXAMPLE
+Publish-AspNet -packOutput $packOutput -publishProperties @{
+ 'WebPublishMethod'='MSDeploy'
+ 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';`
+'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="$env:PublishPwd"
+ 'ExcludeFiles'=@(
+ @{'absolutepath'='test.txt'},
+ @{'absolutepath'='references.js'}
+)}
+
+.EXAMPLE
+Publish-AspNet -packOutput $packOutput -publishProperties @{
+ 'WebPublishMethod'='FileSystem'
+ 'publishUrl'="$publishDest"
+ 'ExcludeFiles'=@(
+ @{'absolutepath'='test.txt'},
+ @{'absolutepath'='_references.js'})
+ 'Replacements' = @(
+ @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'})
+ }
+
+Publish-AspNet -packOutput $packOutput -publishProperties @{
+ 'WebPublishMethod'='FileSystem'
+ 'publishUrl'="$publishDest"
+ 'ExcludeFiles'=@(
+ @{'absolutepath'='test.txt'},
+ @{'absolutepath'='c:\\full\\path\\ok\\as\\well\\_references.js'})
+ 'Replacements' = @(
+ @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'})
+ }
+
+.EXAMPLE
+Publish-AspNet -packOutput $packOutput -publishProperties @{
+ 'WebPublishMethod'='FileSystem'
+ 'publishUrl'="$publishDest"
+ 'EnableMSDeployAppOffline'='true'
+ 'AppOfflineTemplate'='offline-template.html'
+ 'MSDeployUseChecksum'='true'
+}
+#>
+function Publish-AspNet{
+ param(
+ [Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ [hashtable]$publishProperties = @{},
+
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ [System.IO.FileInfo]$packOutput,
+
+ [Parameter(Position=2,ValueFromPipelineByPropertyName=$true)]
+ [System.IO.FileInfo]$pubProfilePath
+ )
+ process{
+ if($publishProperties['WebPublishMethodOverride']){
+ 'Overriding publish method from $publishProperties[''WebPublishMethodOverride''] to [{0}]' -f ($publishProperties['WebPublishMethodOverride']) | Write-Verbose
+ $publishProperties['WebPublishMethod'] = $publishProperties['WebPublishMethodOverride']
+ }
+
+ if(-not [string]::IsNullOrWhiteSpace($pubProfilePath)){
+ $profileProperties = Get-PropertiesFromPublishProfile -filepath $pubProfilePath
+ foreach($key in $profileProperties.Keys){
+ if(-not ($publishProperties.ContainsKey($key))){
+ 'Adding properties from publish profile [''{0}''=''{1}'']' -f $key,$profileProperties[$key] | Write-Verbose
+ $publishProperties.Add($key,$profileProperties[$key])
+ }
+ }
+ }
+
+ if(!([System.IO.Path]::IsPathRooted($packOutput))){
+ $packOutput = [System.IO.Path]::GetFullPath((Join-Path $pwd $packOutput))
+ }
+
+ $pubMethod = $publishProperties['WebPublishMethod']
+ 'Publishing with publish method [{0}]' -f $pubMethod | Write-Output
+
+ # get the handler based on WebPublishMethod, and call it.
+ &(Get-AspnetPublishHandler -name $pubMethod) $publishProperties $packOutput
+ }
+}
+
+<#
+.SYNOPSIS
+
+Inputs:
+
+Example of $xmlDocument: ''
+Example of $providerDataArray:
+
+ [System.Collections.ArrayList]$providerDataArray = @()
+
+ $iisAppSourceKeyValue=@{"iisApp" = @{"path"='c:\temp\pathtofiles';"appOfflineTemplate" ='offline-template.html'}}
+ $providerDataArray.Add($iisAppSourceKeyValue)
+
+ $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile"}}
+ $providerDataArray.Add($dbfullsqlKeyValue)
+
+ $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile2"}}
+ $providerDataArray.Add($dbfullsqlKeyValue)
+
+ Manifest File content:
+
+
+
+
+
+
+#>
+function AddInternal-ProviderDataToManifest {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true, Position=0)]
+ [XML]$xmlDocument,
+ [Parameter(Position=1)]
+ [System.Collections.ArrayList]$providerDataArray
+ )
+ process {
+ $siteNode = $xmlDocument.SelectSingleNode("/sitemanifest")
+ if ($siteNode -eq $null) {
+ throw 'sitemanifest element is missing in the xml object'
+ }
+ foreach ($providerData in $providerDataArray) {
+ foreach ($providerName in $providerData.Keys) {
+ $providerValue = $providerData[$providerName]
+ $xmlNode = $xmlDocument.CreateElement($providerName)
+ foreach ($providerValueKey in $providerValue.Keys) {
+ $xmlNode.SetAttribute($providerValueKey, $providerValue[$providerValueKey]) | Out-Null
+ }
+ $siteNode.AppendChild($xmlNode) | Out-Null
+ }
+ }
+ }
+}
+
+function AddInternal-ProjectGuidToWebConfig {
+ [cmdletbinding()]
+ param(
+ [Parameter(Position=0)]
+ [HashTable]$publishProperties,
+ [Parameter(Position=1)]
+ [System.IO.FileInfo]$packOutput
+ )
+ process {
+ try {
+ [Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null
+ $webConfigPath = Join-Path $packOutput 'web.config'
+ $projectGuidCommentValue = 'ProjectGuid: {0}' -f $publishProperties['ProjectGuid']
+ $xDoc = [System.Xml.Linq.XDocument]::Load($webConfigPath)
+ $allNodes = $xDoc.DescendantNodes()
+ $projectGuidComment = $allNodes | Where-Object { $_.NodeType -eq [System.Xml.XmlNodeType]::Comment -and $_.Value -eq $projectGuidCommentValue } | Select -First 1
+ if($projectGuidComment -ne $null) {
+ if($publishProperties['IgnoreProjectGuid'] -eq $true) {
+ $projectGuidComment.Remove() | Out-Null
+ $xDoc.Save($webConfigPath) | Out-Null
+ }
+ }
+ else {
+ if(-not ($publishProperties['IgnoreProjectGuid'] -eq $true)) {
+ $projectGuidComment = New-Object -TypeName System.Xml.Linq.XComment -ArgumentList $projectGuidCommentValue
+ $xDoc.LastNode.AddAfterSelf($projectGuidComment) | Out-Null
+ $xDoc.Save($webConfigPath) | Out-Null
+ }
+ }
+ }
+ catch {
+ }
+ }
+}
+
+<#
+.SYNOPSIS
+
+Example of $EFMigrations:
+ $EFMigrations = @{'CarContext'='Car Context ConnectionString';'MovieContext'='Movie Context Connection String'}
+
+#>
+
+function GenerateInternal-EFMigrationScripts {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true,Position=0)]
+ [System.IO.FileInfo]$projectPath,
+ [Parameter(Mandatory=$true,Position=1)]
+ [System.IO.FileInfo]$packOutput,
+ [Parameter(Position=2)]
+ [HashTable]$EFMigrations
+ )
+ process {
+ $files = @{}
+ $dotnetExePath = GetInternal-DotNetExePath
+ foreach ($dbContextName in $EFMigrations.Keys) {
+ try
+ {
+ $tempDir = GetInternal-PublishTempPath -packOutput $packOutput
+ $efScriptFile = Join-Path $tempDir ('{0}.sql' -f $dbContextName)
+ $arg = ('ef migrations script --idempotent --output {0} --context {1}' -f
+ $efScriptFile,
+ $dbContextName)
+
+ Execute-Command $dotnetExePath $arg $projectPath | Out-Null
+ if (Test-Path -Path $efScriptFile) {
+ if (!($files.ContainsKey($dbContextName))) {
+ $files.Add($dbContextName, $efScriptFile) | Out-Null
+ }
+ }
+ }
+ catch
+ {
+ throw 'error occured when executing dotnet.exe to generate EF T-SQL file'
+ }
+ }
+ # return files object
+ $files
+ }
+}
+
+<#
+.SYNOPSIS
+
+Example of $connectionStrings:
+ $connectionStrings = @{'DefaultConnection'='Default ConnectionString';'CarConnection'='Car Connection String'}
+
+#>
+function GenerateInternal-AppSettingsFile {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory = $true,Position=0)]
+ [System.IO.FileInfo]$packOutput,
+ [Parameter(Mandatory = $true,Position=1)]
+ [string]$environmentName,
+ [Parameter(Position=2)]
+ [HashTable]$connectionStrings
+ )
+ process {
+ $configProdJsonFile = 'appsettings.{0}.json' -f $environmentName
+ $configProdJsonFilePath = Join-Path -Path $packOutput -ChildPath $configProdJsonFile
+
+ if ([string]::IsNullOrEmpty($configProdJsonFilePath)) {
+ throw ('The path of {0} is empty' -f $configProdJsonFilePath)
+ }
+
+ if(!(Test-Path -Path $configProdJsonFilePath)) {
+ # create new file
+ '{}' | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force
+ }
+
+ $jsonObj = ConvertFrom-Json -InputObject (Get-Content -Path $configProdJsonFilePath -Raw)
+ # update when there exists one or more connection strings
+ if ($connectionStrings -ne $null) {
+ foreach ($name in $connectionStrings.Keys) {
+ #check for hierarchy style
+ if ($jsonObj.ConnectionStrings.$name) {
+ $jsonObj.ConnectionStrings.$name = $connectionStrings[$name]
+ continue
+ }
+ #check for horizontal style
+ $horizontalName = 'ConnectionStrings.{0}:' -f $name
+ if ($jsonObj.$horizontalName) {
+ $jsonObj.$horizontalName = $connectionStrings[$name]
+ continue
+ }
+ # create new one
+ if (!($jsonObj.ConnectionStrings)) {
+ $contentForDefaultConnection = '{}'
+ $jsonObj | Add-Member -name 'ConnectionStrings' -value (ConvertFrom-Json -InputObject $contentForDefaultConnection) -MemberType NoteProperty | Out-Null
+ }
+ if (!($jsonObj.ConnectionStrings.$name)) {
+ $jsonObj.ConnectionStrings | Add-Member -name $name -value $connectionStrings[$name] -MemberType NoteProperty | Out-Null
+ }
+ }
+ }
+
+ $jsonObj | ConvertTo-Json | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force
+
+ #return the path of config.[environment].json
+ $configProdJsonFilePath
+ }
+}
+
+<#
+.SYNOPSIS
+
+Inputs:
+Example of $providerDataArray:
+
+ [System.Collections.ArrayList]$providerDataArray = @()
+
+ $iisAppSourceKeyValue=@{"iisApp" = @{"path"='c:\temp\pathtofiles';"appOfflineTemplate" ='offline-template.html'}}
+ $providerDataArray.Add($iisAppSourceKeyValue)
+
+ $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile"}}
+ $providerDataArray.Add($dbfullsqlKeyValue)
+
+ $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile2"}}
+ $providerDataArray.Add($dbfullsqlKeyValue)
+
+ Manifest File content:
+
+
+
+
+
+
+
+#>
+
+function GenerateInternal-ManifestFile {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true,Position=0)]
+ [System.IO.FileInfo]$packOutput,
+ [Parameter(Mandatory=$true,Position=1)]
+ $publishProperties,
+ [Parameter(Mandatory=$true,Position=2)]
+ [System.Collections.ArrayList]$providerDataArray,
+ [Parameter(Mandatory=$true,Position=3)]
+ [ValidateNotNull()]
+ $manifestFileName
+ )
+ process{
+ $xmlDocument = [xml]''
+ AddInternal-ProviderDataToManifest -xmlDocument $xmlDocument -providerDataArray $providerDataArray | Out-Null
+ $publishTempDir = GetInternal-PublishTempPath -packOutput $packOutput
+ $XMLFile = Join-Path $publishTempDir $manifestFileName
+ $xmlDocument.OuterXml | out-file -encoding utf8 -filePath $XMLFile -Force
+
+ # return
+ [System.IO.FileInfo]$XMLFile
+ }
+}
+
+function GetInternal-PublishTempPath {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true, Position=0)]
+ [System.IO.FileInfo]$packOutput
+ )
+ process {
+ $tempDir = [io.path]::GetTempPath()
+ $packOutputFolderName = Split-Path $packOutput -Leaf
+ $publishTempDir = [io.path]::combine($tempDir,'PublishTemp','obj',$packOutputFolderName)
+ if (!(Test-Path -Path $publishTempDir)) {
+ New-Item -Path $publishTempDir -type directory | Out-Null
+ }
+ # return
+ [System.IO.FileInfo]$publishTempDir
+ }
+}
+
+function Publish-AspNetMSDeploy{
+ param(
+ [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ $publishProperties,
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ $packOutput
+ )
+ process{
+ if($publishProperties){
+ $publishPwd = $publishProperties['Password']
+
+ $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput
+ $iisAppPath = $publishProperties['DeployIisAppPath']
+
+ # create source manifest
+
+ # e.g
+ #
+ #
+ #
+ #
+ #
+ #
+
+ [System.Collections.ArrayList]$providerDataArray = @()
+ $iisAppValues = @{"path"=$packOutput};
+ $iisAppSourceKeyValue=@{"iisApp" = $iisAppValues}
+ $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null
+
+ if ($sharedArgs.EFMigrationData -ne $null -and $sharedArgs.EFMigrationData.Contains('EFSqlFiles')) {
+ foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) {
+ $dbFullSqlSourceKeyValue=@{"dbFullSql" = @{"path"=$sqlFile}}
+ $providerDataArray.Add($dbFullSqlSourceKeyValue) | Out-Null
+ }
+ }
+
+ [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'
+
+ $providerDataArray.Clear() | Out-Null
+ # create destination manifest
+
+ # e.g
+ #
+ #
+ #
+ #
+ #
+
+ $iisAppValues = @{"path"=$iisAppPath};
+ if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){
+ $iisAppValues.Add("appOfflineTemplate", $publishProperties['AppOfflineTemplate']) | Out-Null
+ }
+
+ $iisAppDestinationKeyValue=@{"iisApp" = $iisAppValues}
+ $providerDataArray.Add($iisAppDestinationKeyValue) | Out-Null
+
+ if ($publishProperties['EfMigrations'] -ne $null -and $publishProperties['EfMigrations'].Count -gt 0) {
+ foreach ($connectionString in $publishProperties['EfMigrations'].Values) {
+ $dbFullSqlDestinationKeyValue=@{"dbFullSql" = @{"path"=$connectionString}}
+ $providerDataArray.Add($dbFullSqlDestinationKeyValue) | Out-Null
+ }
+ }
+
+
+ [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml'
+
+ <#
+ "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe"
+ -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml'
+ -dest:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\DestManifest.xml',ComputerName='https://contoso.scm.azurewebsites.net/msdeploy.axd',UserName='$contoso',Password='',IncludeAcls='False',AuthType='Basic'
+ -verb:sync
+ -enableRule:DoNotDeleteRule
+ -retryAttempts=2"
+ #>
+
+ if(-not [string]::IsNullOrWhiteSpace($publishProperties['MSDeployPublishMethod'])){
+ $serviceMethod = $publishProperties['MSDeployPublishMethod']
+ }
+
+ $msdeployComputerName= InternalNormalize-MSDeployUrl -serviceUrl $publishProperties['MSDeployServiceURL'] -siteName $iisAppPath -serviceMethod $publishProperties['MSDeployPublishMethod']
+ if($publishProperties['UseMSDeployServiceURLAsIs'] -eq $true){
+ $msdeployComputerName = $publishProperties['MSDeployServiceURL']
+ }
+
+ $publishArgs = @()
+ #use manifest to publish
+ $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)
+ $publishArgs += ('-dest:manifest=''{0}'',ComputerName=''{1}'',UserName=''{2}'',Password=''{3}'',IncludeAcls=''False'',AuthType=''{4}''{5}' -f
+ $destXMLFile.FullName,
+ $msdeployComputerName,
+ $publishProperties['UserName'],
+ $publishPwd,
+ $publishProperties['AuthType'],
+ $sharedArgs.DestFragment)
+ $publishArgs += '-verb:sync'
+ $publishArgs += $sharedArgs.ExtraArgs
+
+ $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')
+
+ if (! [String]::IsNullOrEmpty($publishPwd)) {
+ $command.Replace($publishPwd,'{PASSWORD-REMOVED-FROM-LOG}') | Print-CommandString
+ }
+ Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')
+ }
+ else{
+ throw 'publishProperties is empty, cannot publish'
+ }
+ }
+}
+
+function Escape-TextForRegularExpressions{
+ [cmdletbinding()]
+ param(
+ [Parameter(Position=0,Mandatory=$true)]
+ [string]$text
+ )
+ process{
+ [regex]::Escape($text)
+ }
+}
+
+function Publish-AspNetMSDeployPackage{
+ param(
+ [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ $publishProperties,
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ $packOutput
+ )
+ process{
+ if($publishProperties){
+ $packageDestinationFilepath = $publishProperties['DesktopBuildPackageLocation']
+
+ if(!$packageDestinationFilepath){
+ throw ('The package destination property (DesktopBuildPackageLocation) was not found in the publish properties')
+ }
+
+ if(!([System.IO.Path]::IsPathRooted($packageDestinationFilepath))){
+ $packageDestinationFilepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $packageDestinationFilepath))
+ }
+
+ # if the dir doesn't exist create it
+ $pkgDir = ((new-object -typename System.IO.FileInfo($packageDestinationFilepath)).Directory)
+ if(!(Test-Path -Path $pkgDir)) {
+ New-Item $pkgDir -type Directory | Out-Null
+ }
+
+ <#
+ "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe"
+ -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml'
+ -dest:package=c:\temp\path\contosoweb.zip
+ -verb:sync
+ -enableRule:DoNotDeleteRule
+ -retryAttempts=2
+ #>
+
+ $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput
+
+ # create source manifest
+
+ # e.g
+ #
+ #
+ #
+ #
+
+ [System.Collections.ArrayList]$providerDataArray = @()
+ $iisAppSourceKeyValue=@{"iisApp" = @{"path"=$packOutput}}
+ $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null
+
+ [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'
+
+ $publishArgs = @()
+ $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)
+ $publishArgs += ('-dest:package=''{0}''' -f $packageDestinationFilepath)
+ $publishArgs += '-verb:sync'
+ $packageContentFolder = $publishProperties['MSDeployPackageContentFoldername']
+ if(!$packageContentFolder){ $packageContentFolder = 'website' }
+ $publishArgs += ('-replace:match=''{0}'',replace=''{1}''' -f (Escape-TextForRegularExpressions $packOutput), $packageContentFolder )
+ $publishArgs += $sharedArgs.ExtraArgs
+
+ $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')
+ $command | Print-CommandString
+ Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')
+ }
+ else{
+ throw 'publishProperties is empty, cannot publish'
+ }
+ }
+}
+
+function Publish-AspNetFileSystem{
+ param(
+ [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ $publishProperties,
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ $packOutput
+ )
+ process{
+ $pubOut = $publishProperties['publishUrl']
+
+ if([string]::IsNullOrWhiteSpace($pubOut)){
+ throw ('publishUrl is a required property for FileSystem publish but it was empty.')
+ }
+
+ # if it's a relative path then update it to a full path
+ if(!([System.IO.Path]::IsPathRooted($pubOut))){
+ $pubOut = [System.IO.Path]::GetFullPath((Join-Path $pwd $pubOut))
+ $publishProperties['publishUrl'] = "$pubOut"
+ }
+
+ 'Publishing files to {0}' -f $pubOut | Write-Output
+
+ # we use msdeploy.exe because it supports incremental publish/skips/replacements/etc
+ # msdeploy.exe -verb:sync -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml' -dest:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\DestManifest.xml'
+
+ $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput
+
+ # create source manifest
+
+ # e.g
+ #
+ #
+ #
+ #
+
+ [System.Collections.ArrayList]$providerDataArray = @()
+ $contentPathValues = @{"path"=$packOutput};
+ $contentPathSourceKeyValue=@{"contentPath" = $contentPathValues}
+ $providerDataArray.Add($contentPathSourceKeyValue) | Out-Null
+
+ [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'
+
+ $providerDataArray.Clear() | Out-Null
+ # create destination manifest
+
+ # e.g
+ #
+ #
+ #
+ $contentPathValues = @{"path"=$publishProperties['publishUrl']};
+ if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){
+ $contentPathValues.Add("appOfflineTemplate", $publishProperties['AppOfflineTemplate']) | Out-Null
+ }
+ $contentPathDestinationKeyValue=@{"contentPath" = $contentPathValues}
+ $providerDataArray.Add($contentPathDestinationKeyValue) | Out-Null
+
+ [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml'
+
+ $publishArgs = @()
+ $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)
+ $publishArgs += ('-dest:manifest=''{0}''{1}' -f $destXMLFile.FullName, $sharedArgs.DestFragment)
+ $publishArgs += '-verb:sync'
+ $publishArgs += $sharedArgs.ExtraArgs
+
+ $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')
+ $command | Print-CommandString
+ Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')
+
+ # copy sql script to script folder
+ if (($sharedArgs.EFMigrationData['EFSqlFiles'] -ne $null) -and ($sharedArgs.EFMigrationData['EFSqlFiles'].Count -gt 0)) {
+ $scriptsDir = Join-Path $pubOut 'efscripts'
+
+ if (!(Test-Path -Path $scriptsDir)) {
+ New-Item -Path $scriptsDir -type directory | Out-Null
+ }
+
+ foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) {
+ Copy-Item $sqlFile -Destination $scriptsDir -Force -Recurse | Out-Null
+ }
+ }
+ }
+}
+
+<#
+.SYNOPSIS
+ This can be used to read a publish profile to extract the property values into a hashtable.
+
+.PARAMETER filepath
+ Path to the publish profile to get the properties from. Currenlty this only supports reading
+ .pubxml files.
+
+.EXAMPLE
+ Get-PropertiesFromPublishProfile -filepath c:\projects\publish\devpublish.pubxml
+#>
+function Get-PropertiesFromPublishProfile{
+ [cmdletbinding()]
+ param(
+ [Parameter(Position=0,Mandatory=$true)]
+ [ValidateNotNull()]
+ [ValidateScript({Test-Path $_})]
+ [System.IO.FileInfo]$filepath
+ )
+ begin{
+ Add-Type -AssemblyName System.Core
+ Add-Type -AssemblyName Microsoft.Build
+ }
+ process{
+ 'Reading publish properties from profile [{0}]' -f $filepath | Write-Verbose
+ # use MSBuild to get the project and read properties
+ $projectCollection = (New-Object Microsoft.Build.Evaluation.ProjectCollection)
+ if(!([System.IO.Path]::IsPathRooted($filepath))){
+ $filepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $filepath))
+ }
+ $project = ([Microsoft.Build.Construction.ProjectRootElement]::Open([string]$filepath.Fullname, $projectCollection))
+
+ $properties = @{}
+ foreach($property in $project.Properties){
+ $properties[$property.Name]=$property.Value
+ }
+
+ $properties
+ }
+}
+
+function Print-CommandString{
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
+ $command
+ )
+ process{
+ 'Executing command [{0}]' -f $command | Write-Output
+ }
+}
+
+function Execute-CommandString{
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
+ [string[]]$command,
+
+ [switch]
+ $useInvokeExpression,
+
+ [switch]
+ $ignoreErrors
+ )
+ process{
+ foreach($cmdToExec in $command){
+ 'Executing command [{0}]' -f $cmdToExec | Write-Verbose
+ if($useInvokeExpression){
+ try {
+ Invoke-Expression -Command $cmdToExec
+ }
+ catch {
+ if(-not $ignoreErrors){
+ $msg = ('The command [{0}] exited with exception [{1}]' -f $cmdToExec, $_.ToString())
+ throw $msg
+ }
+ }
+ }
+ else {
+ cmd.exe /D /C $cmdToExec
+
+ if(-not $ignoreErrors -and ($LASTEXITCODE -ne 0)){
+ $msg = ('The command [{0}] exited with code [{1}]' -f $cmdToExec, $LASTEXITCODE)
+ throw $msg
+ }
+ }
+ }
+ }
+}
+
+function Execute-Command {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ [String]$exePath,
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ [String]$arguments,
+ [Parameter(Position=2)]
+ [System.IO.FileInfo]$workingDirectory
+ )
+ process{
+ $psi = New-Object -TypeName System.Diagnostics.ProcessStartInfo
+ $psi.CreateNoWindow = $true
+ $psi.UseShellExecute = $false
+ $psi.RedirectStandardOutput = $true
+ $psi.RedirectStandardError=$true
+ $psi.FileName = $exePath
+ $psi.Arguments = $arguments
+ if($workingDirectory -and (Test-Path -Path $workingDirectory)) {
+ $psi.WorkingDirectory = $workingDirectory
+ }
+
+ $process = New-Object -TypeName System.Diagnostics.Process
+ $process.StartInfo = $psi
+ $process.EnableRaisingEvents=$true
+
+ # Register the event handler for error
+ $stdErrEvent = Register-ObjectEvent -InputObject $process -EventName 'ErrorDataReceived' -Action {
+ if (! [String]::IsNullOrEmpty($EventArgs.Data)) {
+ $EventArgs.Data | Write-Error
+ }
+ }
+
+ # Starting process.
+ $process.Start() | Out-Null
+ $process.BeginErrorReadLine() | Out-Null
+ $output = $process.StandardOutput.ReadToEnd()
+ $process.WaitForExit() | Out-Null
+ $output | Write-Output
+
+ # UnRegister the event handler for error
+ Unregister-Event -SourceIdentifier $stdErrEvent.Name | Out-Null
+ }
+}
+
+
+function GetInternal-DotNetExePath {
+ process {
+ $dotnetinstallpath = $env:dotnetinstallpath
+ if (!$dotnetinstallpath) {
+ $DotNetRegItem = Get-ItemProperty -Path 'hklm:\software\dotnet\setup\'
+ if ($env:DOTNET_HOME) {
+ $dotnetinstallpath = Join-Path $env:DOTNET_HOME -ChildPath 'dotnet.exe'
+ }
+ elseif ($DotNetRegItem -and $DotNetRegItem.InstallDir){
+ $dotnetinstallpath = Join-Path $DotNetRegItem.InstallDir -ChildPath 'dotnet.exe'
+ }
+ }
+ if (!(Test-Path $dotnetinstallpath)) {
+ throw 'Unable to find dotnet.exe, please install it and try again'
+ }
+ # return
+ [System.IO.FileInfo]$dotnetinstallpath
+ }
+}
+
+function Get-MSDeploy{
+ [cmdletbinding()]
+ param()
+ process{
+ $installPath = $env:msdeployinstallpath
+
+ if(!$installPath){
+ $keysToCheck = @('hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\3','hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\2','hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\1')
+
+ foreach($keyToCheck in $keysToCheck){
+ if(Test-Path $keyToCheck){
+ $installPath = (Get-itemproperty $keyToCheck -Name InstallPath -ErrorAction SilentlyContinue | select -ExpandProperty InstallPath -ErrorAction SilentlyContinue)
+ }
+
+ if($installPath){
+ break;
+ }
+ }
+ }
+
+ if(!$installPath){
+ throw "Unable to find msdeploy.exe, please install it and try again"
+ }
+
+ [string]$msdInstallLoc = (join-path $installPath 'msdeploy.exe')
+
+ "Found msdeploy.exe at [{0}]" -f $msdInstallLoc | Write-Verbose
+
+ $msdInstallLoc
+ }
+}
+
+function InternalNormalize-MSDeployUrl{
+ [cmdletbinding()]
+ param(
+ [Parameter(Position=0,Mandatory=$true)]
+ [string]$serviceUrl,
+
+ [string] $siteName,
+
+ [ValidateSet('WMSVC','RemoteAgent','InProc')]
+ [string]$serviceMethod = 'WMSVC'
+ )
+ process{
+ $tempUrl = $serviceUrl
+ $resultUrl = $serviceUrl
+
+ $httpsStr = 'https://'
+ $httpStr = 'http://'
+ $msdeployAxd = 'msdeploy.axd'
+
+ if(-not [string]::IsNullOrWhiteSpace($serviceUrl)){
+ if([string]::Compare($serviceMethod,'WMSVC',[StringComparison]::OrdinalIgnoreCase) -eq 0){
+ # if no http or https then add one
+ if(-not ($serviceUrl.StartsWith($httpStr,[StringComparison]::OrdinalIgnoreCase) -or
+ $serviceUrl.StartsWith($httpsStr,[StringComparison]::OrdinalIgnoreCase)) ){
+
+ $serviceUrl = [string]::Concat($httpsStr,$serviceUrl.TrimStart())
+ }
+ [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl
+ [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl
+
+ # if it's https and the port was not passed in override it to 8172
+ if( ([string]::Compare('https',$serviceUriBuilder.Scheme,[StringComparison]::OrdinalIgnoreCase) -eq 0) -and
+ -not $serviceUrl.Contains((':{0}' -f $serviceUriBuilder.Port)) ) {
+ $serviceUriBuilder.Port = 8172
+ }
+
+ # if no path then add one
+ if([string]::Compare('/',$serviceUriBuilder.Path,[StringComparison]::OrdinalIgnoreCase) -eq 0){
+ $serviceUriBuilder.Path = $msdeployAxd
+ }
+
+ if ([string]::IsNullOrEmpty($serviceUriBuilder.Query) -and -not([string]::IsNullOrEmpty($siteName)))
+ {
+ $serviceUriBuilder.Query = "site=" + $siteName;
+ }
+
+ $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri
+ }
+ elseif([string]::Compare($serviceMethod,'RemoteAgent',[StringComparison]::OrdinalIgnoreCase) -eq 0){
+ [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl
+ # http://{computername}/MSDEPLOYAGENTSERVICE
+ # remote agent must use http
+ $serviceUriBuilder.Scheme = 'http'
+ $serviceUriBuilder.Path = '/MSDEPLOYAGENTSERVICE'
+
+ $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri
+ }
+ else{
+ # see if it's for localhost
+ [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl
+ $resultUrl = $serviceUri.AbsoluteUri
+ }
+ }
+
+ # return the result to the caller
+ $resultUrl
+ }
+}
+
+function InternalRegister-AspNetKnownPublishHandlers{
+ [cmdletbinding()]
+ param()
+ process{
+ 'Registering MSDeploy handler' | Write-Verbose
+ Register-AspnetPublishHandler -name 'MSDeploy' -force -handler {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ $publishProperties,
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ $packOutput
+ )
+
+ Publish-AspNetMSDeploy -publishProperties $publishProperties -packOutput $packOutput
+ }
+
+ 'Registering MSDeploy package handler' | Write-Verbose
+ Register-AspnetPublishHandler -name 'Package' -force -handler {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ $publishProperties,
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ $packOutput
+ )
+
+ Publish-AspNetMSDeployPackage -publishProperties $publishProperties -packOutput $packOutput
+ }
+
+ 'Registering FileSystem handler' | Write-Verbose
+ Register-AspnetPublishHandler -name 'FileSystem' -force -handler {
+ [cmdletbinding()]
+ param(
+ [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
+ $publishProperties,
+ [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]
+ $packOutput
+ )
+
+ Publish-AspNetFileSystem -publishProperties $publishProperties -packOutput $packOutput
+ }
+ }
+}
+
+<#
+.SYNOPSIS
+ Used for testing purposes only.
+#>
+function InternalReset-AspNetPublishHandlers{
+ [cmdletbinding()]
+ param()
+ process{
+ $script:AspNetPublishHandlers = @{}
+ InternalRegister-AspNetKnownPublishHandlers
+ }
+}
+
+Export-ModuleMember -function Get-*,Publish-*,Register-*,Enable-*
+if($env:IsDeveloperMachine){
+ # you can set the env var to expose all functions to importer. easy for development.
+ # this is required for executing pester test cases, it's set by build.ps1
+ Export-ModuleMember -function *
+}
+
+# register the handlers so that Publish-AspNet can be called
+InternalRegister-AspNetKnownPublishHandlers
+
diff --git a/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-debug-publish.ps1 b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-debug-publish.ps1
new file mode 100644
index 0000000..14c8f20
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-debug-publish.ps1
@@ -0,0 +1,19 @@
+[cmdletbinding(SupportsShouldProcess=$true)]
+param($publishProperties=@{}, $packOutput, $pubProfilePath)
+
+# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327
+
+try{
+ if ($publishProperties['ProjectGuid'] -eq $null){
+ $publishProperties['ProjectGuid'] = 'ba69f132-3891-4c04-8e54-8161754ebdc6'
+ }
+
+ $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1'
+ Import-Module $publishModulePath -DisableNameChecking -Force
+
+ # call Publish-AspNet to perform the publish operation
+ Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath
+}
+catch{
+ "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error
+}
\ No newline at end of file
diff --git a/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-debug.pubxml b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-debug.pubxml
new file mode 100644
index 0000000..5dfebbc
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-debug.pubxml
@@ -0,0 +1,20 @@
+
+
+
+
+ FileSystem
+ Debug
+ Any CPU
+
+ True
+ False
+ netstandard1.6
+ ubuntu.14.04-x64
+ True
+ publish\ubuntu.14.04-x64-debug
+ True
+
+
\ No newline at end of file
diff --git a/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-release-publish.ps1 b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-release-publish.ps1
new file mode 100644
index 0000000..14c8f20
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-release-publish.ps1
@@ -0,0 +1,19 @@
+[cmdletbinding(SupportsShouldProcess=$true)]
+param($publishProperties=@{}, $packOutput, $pubProfilePath)
+
+# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327
+
+try{
+ if ($publishProperties['ProjectGuid'] -eq $null){
+ $publishProperties['ProjectGuid'] = 'ba69f132-3891-4c04-8e54-8161754ebdc6'
+ }
+
+ $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1'
+ Import-Module $publishModulePath -DisableNameChecking -Force
+
+ # call Publish-AspNet to perform the publish operation
+ Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath
+}
+catch{
+ "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error
+}
\ No newline at end of file
diff --git a/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-release.pubxml b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-release.pubxml
new file mode 100644
index 0000000..c7baf1d
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/ubuntu.14.04-x64-release.pubxml
@@ -0,0 +1,19 @@
+
+
+
+
+ FileSystem
+ Release
+ Any CPU
+
+ True
+ False
+
+ True
+ .\publish\linux-release
+ False
+
+
\ No newline at end of file
diff --git a/gtaserver.core/Properties/PublishProfiles/ubuntu.16.04-x64-debug-publish.ps1 b/gtaserver.core/Properties/PublishProfiles/ubuntu.16.04-x64-debug-publish.ps1
new file mode 100644
index 0000000..14c8f20
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/ubuntu.16.04-x64-debug-publish.ps1
@@ -0,0 +1,19 @@
+[cmdletbinding(SupportsShouldProcess=$true)]
+param($publishProperties=@{}, $packOutput, $pubProfilePath)
+
+# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327
+
+try{
+ if ($publishProperties['ProjectGuid'] -eq $null){
+ $publishProperties['ProjectGuid'] = 'ba69f132-3891-4c04-8e54-8161754ebdc6'
+ }
+
+ $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1'
+ Import-Module $publishModulePath -DisableNameChecking -Force
+
+ # call Publish-AspNet to perform the publish operation
+ Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath
+}
+catch{
+ "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error
+}
\ No newline at end of file
diff --git a/gtaserver.core/Properties/PublishProfiles/win7-x64-debug-publish.ps1 b/gtaserver.core/Properties/PublishProfiles/win7-x64-debug-publish.ps1
new file mode 100644
index 0000000..14c8f20
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/win7-x64-debug-publish.ps1
@@ -0,0 +1,19 @@
+[cmdletbinding(SupportsShouldProcess=$true)]
+param($publishProperties=@{}, $packOutput, $pubProfilePath)
+
+# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327
+
+try{
+ if ($publishProperties['ProjectGuid'] -eq $null){
+ $publishProperties['ProjectGuid'] = 'ba69f132-3891-4c04-8e54-8161754ebdc6'
+ }
+
+ $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1'
+ Import-Module $publishModulePath -DisableNameChecking -Force
+
+ # call Publish-AspNet to perform the publish operation
+ Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath
+}
+catch{
+ "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error
+}
\ No newline at end of file
diff --git a/gtaserver.core/Properties/PublishProfiles/win7-x64-debug.pubxml b/gtaserver.core/Properties/PublishProfiles/win7-x64-debug.pubxml
new file mode 100644
index 0000000..8ee468e
--- /dev/null
+++ b/gtaserver.core/Properties/PublishProfiles/win7-x64-debug.pubxml
@@ -0,0 +1,20 @@
+
+
+
+
+ FileSystem
+ Debug
+ Any CPU
+
+ True
+ False
+ netstandard1.6
+ win7-x64
+ True
+ publish\win7-x64-debug
+ True
+
+
\ No newline at end of file
diff --git a/gtaserver.core/Properties/launchSettings.json b/gtaserver.core/Properties/launchSettings.json
new file mode 100644
index 0000000..1d8f36e
--- /dev/null
+++ b/gtaserver.core/Properties/launchSettings.json
@@ -0,0 +1,7 @@
+{
+ "profiles": {
+ "gtaserver.core netstandard/win7-x64": {
+ "executablePath": "F:\\Misc\\code\\GTACoOp\\gtaserver.core\\bin\\Debug\\netstandard1.6\\win7-x64\\gtaserver.core.exe"
+ }
+ }
+}
\ No newline at end of file
diff --git a/gtaserver.core/ProtocolMessages/ChatData.cs b/gtaserver.core/ProtocolMessages/ChatData.cs
new file mode 100644
index 0000000..d18da31
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/ChatData.cs
@@ -0,0 +1,17 @@
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages
+{
+ [ProtoContract]
+ public class ChatData
+ {
+ [ProtoMember(1)]
+ public long Id { get; set; }
+
+ [ProtoMember(2)]
+ public string Sender { get; set; }
+
+ [ProtoMember(3)]
+ public string Message { get; set; }
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/ChatMessage.cs b/gtaserver.core/ProtocolMessages/ChatMessage.cs
new file mode 100644
index 0000000..37dd119
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/ChatMessage.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace GTAServer.ProtocolMessages
+{
+ public class ChatMessage
+ {
+ public Client Sender { get; set; }
+ public Client Receiver { get; set; }
+ public bool isPrivate { get; set; }
+ public string Message { get; set; }
+ public ConsoleColor Color { get; set; }
+ public string Prefix { get; set; }
+ public string Suffix { get; set; }
+ public bool Suppress { get; set; }
+
+ public ChatMessage(ChatData chatData, Client client)
+ {
+ Message = chatData.Message;
+ Sender = client;
+ }
+
+ public ChatMessage()
+ {
+ }
+ }
+
+}
diff --git a/gtaserver.core/ProtocolMessages/Client.cs b/gtaserver.core/ProtocolMessages/Client.cs
new file mode 100644
index 0000000..32df24a
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/Client.cs
@@ -0,0 +1,37 @@
+using Lidgren.Network;
+
+namespace GTAServer.ProtocolMessages
+{
+
+ public class Client
+ {
+ public NetConnection NetConnection { get; set; }
+ public string Name { get; set; }
+ public string DisplayName { get; set; }
+ public float Latency { get; set; }
+ public ScriptVersion RemoteScriptVersion { get; set; }
+ public int GameVersion { get; set; }
+ public Vector3 LastKnownPosition { get; set; }
+ public int Health { get; set; }
+ public int VehicleHealth { get; set; }
+ public bool IsInVehicle { get; internal set; }
+ public bool IsAfk { get; set; }
+ public bool Kicked { get; set; }
+ public string KickReason { get; set; }
+ public Client KickedBy { get; set; }
+ public bool Silent { get; set; }
+
+ public Client(NetConnection nc)
+ {
+ NetConnection = nc;
+ }
+
+ public void ApplyConnectionRequest(ConnectionRequest cr)
+ {
+ Name = cr.Name;
+ DisplayName = cr.DisplayName;
+ RemoteScriptVersion = (ScriptVersion)cr.ScriptVersion;
+ GameVersion = cr.GameVersion;
+ }
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/ConnectionRequest.cs b/gtaserver.core/ProtocolMessages/ConnectionRequest.cs
new file mode 100644
index 0000000..51890fe
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/ConnectionRequest.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages
+{
+ [ProtoContract]
+ public class ConnectionRequest
+ {
+ [ProtoMember(1)]
+ public string Name { get; set; }
+
+ [ProtoMember(2)]
+ public string Password { get; set; }
+
+ [ProtoMember(3)]
+ public string DisplayName { get; set; }
+
+ [ProtoMember(4)]
+ public int GameVersion { get; set; }
+
+ [ProtoMember(5)]
+ public byte ScriptVersion { get; set; }
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/DiscoveryResponse.cs b/gtaserver.core/ProtocolMessages/DiscoveryResponse.cs
new file mode 100644
index 0000000..6187f9b
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/DiscoveryResponse.cs
@@ -0,0 +1,21 @@
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages
+{
+ [ProtoContract]
+ public class DiscoveryResponse
+ {
+ [ProtoMember(1)]
+ public string ServerName { get; set; }
+ [ProtoMember(2)]
+ public int MaxPlayers { get; set; }
+ [ProtoMember(3)]
+ public int PlayerCount { get; set; }
+ [ProtoMember(4)]
+ public bool PasswordProtected { get; set; }
+ [ProtoMember(5)]
+ public int Port { get; set; }
+ [ProtoMember(6)]
+ public string Gamemode { get; set; }
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/NativeResponse.cs b/gtaserver.core/ProtocolMessages/NativeResponse.cs
new file mode 100644
index 0000000..5a4f247
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/NativeResponse.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using ProtoBuf;
+
+// I'm just going to keep any natives-related code here.
+namespace GTAServer.ProtocolMessages
+{
+ [ProtoContract]
+ public class NativeResponse
+ {
+ [ProtoMember(1)]
+ public NativeArgument Response { get; set; }
+ [ProtoMember(2)]
+ public string Id { get; set; }
+ }
+
+ [ProtoContract]
+ public class NativeTickCall
+ {
+ [ProtoMember(1)]
+ public NativeData Native { get; set; }
+ [ProtoMember(2)]
+ public string Id { get; set; }
+ }
+
+ [ProtoContract]
+ public class NativeData
+ {
+ [ProtoMember(1)]
+ public ulong Hash { get; set; }
+ [ProtoMember(2)]
+ public List Arguments { get; set; }
+ [ProtoMember(3)]
+ public NativeArgument ReturnType { get; set; }
+ [ProtoMember(4)]
+ public string Id { get; set; }
+ }
+
+ [ProtoContract]
+ [ProtoInclude(2, typeof(IntArgument))]
+ [ProtoInclude(3, typeof(UIntArgument))]
+ [ProtoInclude(4, typeof(StringArgument))]
+ [ProtoInclude(5, typeof(FloatArgument))]
+ [ProtoInclude(6, typeof(BooleanArgument))]
+ [ProtoInclude(7, typeof(LocalPlayerArgument))]
+ [ProtoInclude(8, typeof(Vector3Argument))]
+ [ProtoInclude(9, typeof(LocalGamePlayerArgument))]
+ public class NativeArgument
+ {
+ [ProtoMember(1)]
+ public string Id { get; set; }
+ }
+
+ [ProtoContract]
+ public class IntArgument : NativeArgument
+ {
+ [ProtoMember(1)]
+ public int Data { get; set; }
+ }
+
+ [ProtoContract]
+ public class UIntArgument : NativeArgument
+ {
+ [ProtoMember(1)]
+ public uint Data { get; set; }
+ }
+
+ [ProtoContract]
+ public class StringArgument : NativeArgument
+ {
+ [ProtoMember(1)]
+ public string Data { get; set; }
+ }
+
+ [ProtoContract]
+ public class FloatArgument : NativeArgument
+ {
+ [ProtoMember(1)]
+ public float Data { get; set; }
+ }
+
+ [ProtoContract]
+ public class BooleanArgument : NativeArgument
+ {
+ [ProtoMember(1)]
+ public bool Data { get; set; }
+ }
+
+ [ProtoContract]
+ public class Vector3Argument : NativeArgument
+ {
+ [ProtoMember(1)]
+ public float X { get; set; }
+ [ProtoMember(2)]
+ public float Y { get; set; }
+ [ProtoMember(3)]
+ public float Z { get; set; }
+ }
+
+ [ProtoContract]
+ public class LocalPlayerArgument : NativeArgument
+ {
+ }
+
+ [ProtoContract]
+ public class LocalGamePlayerArgument : NativeArgument
+ {
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/NotificationIconType.cs b/gtaserver.core/ProtocolMessages/NotificationIconType.cs
new file mode 100644
index 0000000..00502b0
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/NotificationIconType.cs
@@ -0,0 +1,13 @@
+namespace GTAServer.ProtocolMessages
+{
+ public enum NotificationIconType
+ {
+ Chatbox = 1,
+ Email = 2,
+ AddFriendRequest = 3,
+ Nothing = 4,
+ RightJumpingArrow = 7,
+ RpIcon = 8,
+ DollarIcon = 9
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/NotificationPicType.cs b/gtaserver.core/ProtocolMessages/NotificationPicType.cs
new file mode 100644
index 0000000..f670a4a
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/NotificationPicType.cs
@@ -0,0 +1,37 @@
+namespace GTAServer.ProtocolMessages
+{
+ public enum NotificationPicType
+ {
+ CHAR_DEFAULT,
+ CHAR_FACEBOOK,
+ CHAR_SOCIAL_CLUB,
+ CHAR_CARSITE2,
+ CHAR_BOATSITE,
+ CHAR_BANK_MAZE,
+ CHAR_BANK_FLEECA,
+ CHAR_BANK_BOL,
+ CHAR_MINOTAUR,
+ CHAR_EPSILON,
+ CHAR_MILSITE,
+ CHAR_CARSITE,
+ CHAR_DR_FRIEDLANDER,
+ CHAR_BIKESITE,
+ CHAR_LIFEINVADER,
+ CHAR_PLANESITE,
+ CHAR_MICHAEL,
+ CHAR_FRANKLIN,
+ CHAR_TREVOR,
+ CHAR_SIMEON,
+ CHAR_RON,
+ CHAR_JIMMY,
+ CHAR_LESTER,
+ CHAR_DAVE,
+ CHAR_LAMAR,
+ CHAR_DEVIN,
+ CHAR_AMANDA,
+ CHAR_TRACEY,
+ CHAR_STRETCH,
+ CHAR_WADE,
+ CHAR_MARTIN,
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/PacketTypes.cs b/gtaserver.core/ProtocolMessages/PacketTypes.cs
new file mode 100644
index 0000000..bef127f
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/PacketTypes.cs
@@ -0,0 +1,22 @@
+namespace GTAServer.ProtocolMessages
+{
+ public enum PacketType
+ {
+ VehiclePositionData = 0,
+ ChatData = 1,
+ PlayerDisconnect = 2,
+ PedPositionData = 3,
+ NpcVehPositionData = 4,
+ NpcPedPositionData = 5,
+ WorldSharingStop = 6,
+ DiscoveryResponse = 7,
+ ConnectionRequest = 8,
+ NativeCall = 9,
+ NativeResponse = 10,
+ PlayerSpawned = 11,
+ NativeTick = 12,
+ NativeTickRecall = 13,
+ NativeOnDisconnect = 14,
+ NativeOnDisconnectRecall = 15,
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/PedData.cs b/gtaserver.core/ProtocolMessages/PedData.cs
new file mode 100644
index 0000000..a1da137
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/PedData.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages {
+ [ProtoContract]
+ public class PedData {
+ [ProtoMember(1)]
+ public long Id { get;set; }
+ [ProtoMember(2)]
+ public string Name { get; set; }
+ [ProtoMember(3)]
+ public int PedModelHash { get; set; }
+ [ProtoMember(4)]
+ public Vector3 Position { get; set; }
+ [ProtoMember(5)]
+ public Quaternion Quaternion { get; set; }
+ [ProtoMember(6)]
+ public bool IsJumping { get; set; }
+ [ProtoMember(7)]
+ public bool IsShooting { get; set; }
+ [ProtoMember(8)]
+ public bool IsAiming { get; set; }
+ [ProtoMember(9)]
+ public Vector3 AimCoords { get; set; }
+ [ProtoMember(10)]
+ public int WeaponHash { get; set; }
+ [ProtoMember(11)]
+ public int PlayerHealth { get; set; }
+ [ProtoMember(12)]
+ public float Latency { get; set; }
+ [ProtoMember(13)]
+ public Dictionary PedProps { get; set; }
+ [ProtoMember(14)]
+ public bool IsParachuteOpen { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/gtaserver.core/ProtocolMessages/PlayerDisconnect.cs b/gtaserver.core/ProtocolMessages/PlayerDisconnect.cs
new file mode 100644
index 0000000..26ab87b
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/PlayerDisconnect.cs
@@ -0,0 +1,11 @@
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages
+{
+ [ProtoContract]
+ public class PlayerDisconnect
+ {
+ [ProtoMember(1)]
+ public long Id { get; set; }
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/Quaternion.cs b/gtaserver.core/ProtocolMessages/Quaternion.cs
new file mode 100644
index 0000000..0438941
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/Quaternion.cs
@@ -0,0 +1,15 @@
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages {
+ [ProtoContract]
+ public class Quaternion {
+ [ProtoMember(1)]
+ public float X { get; set; }
+ [ProtoMember(2)]
+ public float Y { get; set; }
+ [ProtoMember(3)]
+ public float Z { get; set; }
+ [ProtoMember(4)]
+ public float W { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/gtaserver.core/ProtocolMessages/ScriptVersion.cs b/gtaserver.core/ProtocolMessages/ScriptVersion.cs
new file mode 100644
index 0000000..9008c8d
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/ScriptVersion.cs
@@ -0,0 +1,15 @@
+namespace GTAServer.ProtocolMessages
+{
+ public enum ScriptVersion
+ {
+ VERSION_UNKNOWN = 0,
+ VERSION_0_6 = 1,
+ VERSION_0_6_1 = 2,
+ VERSION_0_7 = 3,
+ VERSION_0_8_1 = 4,
+ VERSION_0_9 = 5,
+ VERSION_0_9_1 = 6,
+ VERSION_0_9_2 = 7,
+ VERSION_0_9_3 = 8
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/Vector3.cs b/gtaserver.core/ProtocolMessages/Vector3.cs
new file mode 100644
index 0000000..aa26231
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/Vector3.cs
@@ -0,0 +1,37 @@
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages
+{
+ [ProtoContract]
+ public class Vector3
+ {
+ public Vector3()
+ {
+ X = 0f;
+ Y = 0f;
+ Z = 0f;
+ }
+
+ public Vector3(float x, float y, float z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+ ///
+ /// X
+ ///
+ [ProtoMember(1)]
+ public float X { get; set; }
+ ///
+ /// Y
+ ///
+ [ProtoMember(2)]
+ public float Y { get; set; }
+ ///
+ /// Z
+ ///
+ [ProtoMember(3)]
+ public float Z { get; set; }
+ }
+}
diff --git a/gtaserver.core/ProtocolMessages/VehicleData.cs b/gtaserver.core/ProtocolMessages/VehicleData.cs
new file mode 100644
index 0000000..36e4965
--- /dev/null
+++ b/gtaserver.core/ProtocolMessages/VehicleData.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.Numerics;
+using ProtoBuf;
+
+namespace GTAServer.ProtocolMessages
+{
+ [ProtoContract]
+ public class VehicleData
+ {
+ [ProtoMember(1)]
+ public long Id { get; set; }
+ [ProtoMember(2)]
+ public string Name { get; set; }
+ [ProtoMember(3)]
+ public int VehicleModelHash { get; set; }
+ [ProtoMember(4)]
+ public int PedModelHash { get; set; }
+ [ProtoMember(5)]
+ public int PrimaryColor { get; set; }
+ [ProtoMember(6)]
+ public int SecondaryColor { get; set; }
+ [ProtoMember(7)]
+ public Vector3 Position { get; set; }
+ [ProtoMember(8)]
+ public Quaternion Quaternion { get; set; }
+ [ProtoMember(9)]
+ public int VehicleSeat { get; set; }
+ [ProtoMember(10)]
+ public int VehicleHealth { get; set; }
+ [ProtoMember(11)]
+ public int PlayerHealth { get; set; }
+ [ProtoMember(12)]
+ public float Latency { get; set; }
+ [ProtoMember(13)]
+ public Dictionary VehicleMods { get; set; }
+ [ProtoMember(14)]
+ public bool IsPressingHorn { get; set; }
+ [ProtoMember(15)]
+ public bool IsSirenActive { get; set; }
+ [ProtoMember(16)]
+ public float Speed { get; set; }
+ }
+}
diff --git a/gtaserver.core/Publish.ps1 b/gtaserver.core/Publish.ps1
new file mode 100644
index 0000000..e6b23d7
--- /dev/null
+++ b/gtaserver.core/Publish.ps1
@@ -0,0 +1,19 @@
+# A script to generate release publishable builds.
+Add-Type -AssemblyName "system.io.compression.filesystem"
+
+# Remove old outputs
+If (Test-Path publish/windows-Release) { Remove-Item publish/windows-Release -Recurse }
+If (Test-Path publish/linux-Release) { Remove-Item publish/linux-Release -Recurse }
+If (Test-Path publish/windows-Release.zip) { Remove-Item publish/windows-Release.zip }
+If (Test-Path publish/linux-Release.zip) { Remove-Item publish/linux-Release.zip }
+# Build
+dotnet build -r win7-x64 -c Release
+dotnet build -r ubuntu.14.04-x64 -c Release
+
+# Publish
+dotnet publish -r win7-x64 -c Release -o publish/windows-Release
+dotnet publish -r ubuntu.14.04-x64 -c Release -o publish/linux-Release
+
+# Zip
+Compress-Archive -Path publish/windows-Release -DestinationPath publish/windows-Release.zip
+Compress-Archive -Path publish/linux-Release -DestinationPath publish/linux-Release.zip
\ No newline at end of file
diff --git a/gtaserver.core/ServerConfiguration.cs b/gtaserver.core/ServerConfiguration.cs
new file mode 100644
index 0000000..411ffcb
--- /dev/null
+++ b/gtaserver.core/ServerConfiguration.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace GTAServer
+{
+ [XmlType(TypeName = "ServerVariable")]
+ public struct ServerVariable
+ {
+ public string Key { get; set; }
+ public string Value { get; set; }
+ }
+
+ public class ServerConfiguration
+ {
+ public int Port { get; set; } = 4499;
+ public int MaxClients { get; set; } = 16;
+ public string GamemodeName { get; set; } = "freeroam";
+ public string ServerName { get; set; } = "GTACoOp Server";
+ public string Password { get; set; } = "";
+ public string PrimaryMasterServer { get; set; } = "http://46.101.1.92/";
+ public string BackupMasterServer { get; set; } = "https://gtamaster.nofla.me";
+ public bool AnnounceSelf { get; set; } = false;
+ public bool AllowNicknames { get; set; } = true;
+ public bool AllowOutdatedClients { get; set; } = false;
+ public bool DebugMode { get; set; } = false;
+
+ public List ServerPlugins { get; set; } = new List() {};
+
+ public List ServerVariables = new List();
+ }
+}
diff --git a/gtaserver.core/ServerManager.cs b/gtaserver.core/ServerManager.cs
new file mode 100644
index 0000000..cd2062d
--- /dev/null
+++ b/gtaserver.core/ServerManager.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.IO;
+using System.Linq;
+using System.Xml.Serialization;
+using Microsoft.Extensions.Logging;
+using GTAServer.PluginAPI;
+using ProtoBuf.Meta;
+using SimpleConsoleLogger;
+
+namespace GTAServer
+{
+ public class ServerManager
+ {
+ private static ServerConfiguration _gameServerConfiguration;
+ private static ILogger _logger;
+ private static readonly List Plugins=new List();
+ private static readonly string Location = System.AppContext.BaseDirectory;
+ private static bool _debugMode = false;
+ private static int _targetTickTime = 15;
+ private static void CreateNeededFiles()
+ {
+ if (!Directory.Exists(Location + Path.DirectorySeparatorChar + "Plugins")) Directory.CreateDirectory(Location + Path.DirectorySeparatorChar + "Plugins");
+ if (!Directory.Exists(Location + Path.DirectorySeparatorChar + "Configuration")) Directory.CreateDirectory(Location + Path.DirectorySeparatorChar + "Configuration");
+ }
+
+ private static void DoDebugWarning()
+ {
+ if (!_debugMode) return;
+ _logger.LogWarning("Note - This build is a debug build. Please do not share this build and report any issues to Mitchell Monahan (@wolfmitchell)");
+ _logger.LogWarning("Furthermore, debug builds will not announce themselves to the master server, regardless of the AnnounceSelf config option.");
+ _logger.LogWarning("To help bring crashes to the attention of the server owner and make sure they are reported to me, error catching has been disabled in this build.");
+ }
+ public static void Main(string[] args)
+ {
+#if DEBUG
+ _debugMode = true;
+#endif
+ CreateNeededFiles();
+
+ // can't use logger here since the logger config depends on if debug mode is on or off
+ Console.WriteLine("Reading server configuration...");
+ _gameServerConfiguration = LoadServerConfiguration(Location + Path.DirectorySeparatorChar + "Configuration" + Path.DirectorySeparatorChar + "serverSettings.xml");
+ if (!_debugMode) _debugMode = _gameServerConfiguration.DebugMode;
+
+ if (_debugMode)
+ {
+
+ Util.LoggerFactory = new LoggerFactory()
+ .AddSimpleConsole()
+ .AddDebug();
+ }
+ else
+ {
+ Util.LoggerFactory = new LoggerFactory()
+ .AddSimpleConsole((s, l) => (int) l >= (int) LogLevel.Information);
+ }
+ _logger = Util.LoggerFactory.CreateLogger();
+ DoDebugWarning();
+
+ if (_gameServerConfiguration.ServerVariables.Any(v => v.Key == "tickEvery"))
+ {
+ var tpsString = _gameServerConfiguration.ServerVariables.First(v => v.Key == "tickEvery").Value;
+ if (!int.TryParse(tpsString, out _targetTickTime))
+ {
+ _logger.LogError(
+ "Could not set ticks per second from server variable 'tps' (value is not an integer)");
+ }
+ else
+ {
+ _logger.LogInformation("Custom tick rate set. Will try to tick every " + _targetTickTime + "ms");
+ }
+ }
+
+ _logger.LogInformation("Server preparing to start...");
+
+ var gameServer = new GameServer(_gameServerConfiguration.Port, _gameServerConfiguration.ServerName,
+ _gameServerConfiguration.GamemodeName, _debugMode)
+ {
+ Password = _gameServerConfiguration.Password,
+ MasterServer = _gameServerConfiguration.PrimaryMasterServer,
+ BackupMasterServer = _gameServerConfiguration.BackupMasterServer,
+ AnnounceSelf = _gameServerConfiguration.AnnounceSelf,
+ AllowNicknames = _gameServerConfiguration.AllowNicknames,
+ AllowOutdatedClients = _gameServerConfiguration.AllowOutdatedClients,
+ MaxPlayers = _gameServerConfiguration.MaxClients
+ };
+ gameServer.Start();
+
+ // Plugin Code
+ _logger.LogInformation("Loading plugins");
+ //Plugins = PluginLoader.LoadPlugin("TestPlugin");
+ foreach (var pluginName in _gameServerConfiguration.ServerPlugins)
+ {
+ foreach (var loadedPlugin in PluginLoader.LoadPlugin(pluginName))
+ {
+ Plugins.Add(loadedPlugin);
+ }
+ }
+
+ _logger.LogInformation("Plugins loaded. Enabling plugins...");
+ foreach (var plugin in Plugins)
+ {
+ if (!plugin.OnEnable(gameServer, false))
+ {
+ _logger.LogWarning("Plugin " + plugin.Name + " returned false when enabling, marking as disabled, although it may still have hooks registered and called.");
+ }
+ }
+
+ var t = new Timer(doServerTick, gameServer, 0, _targetTickTime);
+ _logger.LogInformation("Starting server main loop, ready to accept connections.");
+ while (true) Thread.Sleep(1);
+ }
+
+ public static void doServerTick(object serverObject)
+ {
+ var server = (GameServer) serverObject;
+ if (_debugMode)
+ {
+ server.Tick();
+ }
+ else
+ {
+ try
+ {
+ server.Tick();
+ }
+ catch (Exception e)
+ {
+ _logger.LogError("Exception while ticking", e);
+ }
+ }
+ }
+ private static ServerConfiguration LoadServerConfiguration(string path)
+ {
+ var ser = new XmlSerializer(typeof(ServerConfiguration));
+
+ ServerConfiguration cfg = null;
+ if (File.Exists(path))
+ {
+ using (var stream = File.OpenRead(path)) cfg = (ServerConfiguration)ser.Deserialize(stream);
+ using (
+ var stream = new FileStream(path, File.Exists(path) ? FileMode.Truncate : FileMode.Create,
+ FileAccess.ReadWrite)) ser.Serialize(stream, cfg);
+ }
+ else
+ {
+ Console.WriteLine("No configuration found, creating a new one.");
+ using (var stream = File.OpenWrite(path)) ser.Serialize(stream, cfg = new ServerConfiguration());
+ }
+ return cfg;
+ }
+ }
+}
diff --git a/gtaserver.core/Util.cs b/gtaserver.core/Util.cs
new file mode 100644
index 0000000..25f4dd8
--- /dev/null
+++ b/gtaserver.core/Util.cs
@@ -0,0 +1,28 @@
+using System.IO;
+using Microsoft.Extensions.Logging;
+using ProtoBuf;
+
+namespace GTAServer
+{
+ public class Util
+ {
+ public static T DeserializeBinary(byte[] data)
+ {
+ using (var stream = new MemoryStream(data))
+ {
+ return Serializer.Deserialize(stream);
+ }
+ }
+
+ public static byte[] SerializeBinary(object data)
+ {
+ using (var stream = new MemoryStream())
+ {
+ Serializer.Serialize(stream, data);
+ return stream.ToArray();
+ }
+ }
+
+ public static ILoggerFactory LoggerFactory;
+ }
+}
diff --git a/gtaserver.core/gtaserver.core.sln b/gtaserver.core/gtaserver.core.sln
new file mode 100644
index 0000000..e52418c
--- /dev/null
+++ b/gtaserver.core/gtaserver.core.sln
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "gtaserver.core", "gtaserver.core.xproj", "{BA69F132-3891-4C04-8E54-8161754EBDC6}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestPlugin", "..\gtaserver.core-plugins\TestPlugin\TestPlugin.xproj", "{8F89F7FB-9685-4C89-9BD5-4C92EE541AC9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{C78C08C7-3A78-4167-BFE8-6673A72A216E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E9B5EBA1-0110-4D60-A668-3CE9A812CB7D}"
+ ProjectSection(SolutionItems) = preProject
+ ..\gtaserver.core-plugins\global.json = ..\gtaserver.core-plugins\global.json
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BA69F132-3891-4C04-8E54-8161754EBDC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BA69F132-3891-4C04-8E54-8161754EBDC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BA69F132-3891-4C04-8E54-8161754EBDC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BA69F132-3891-4C04-8E54-8161754EBDC6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8F89F7FB-9685-4C89-9BD5-4C92EE541AC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8F89F7FB-9685-4C89-9BD5-4C92EE541AC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8F89F7FB-9685-4C89-9BD5-4C92EE541AC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8F89F7FB-9685-4C89-9BD5-4C92EE541AC9}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {8F89F7FB-9685-4C89-9BD5-4C92EE541AC9} = {C78C08C7-3A78-4167-BFE8-6673A72A216E}
+ EndGlobalSection
+EndGlobal
diff --git a/gtaserver.core/gtaserver.core.xproj b/gtaserver.core/gtaserver.core.xproj
new file mode 100644
index 0000000..040bf33
--- /dev/null
+++ b/gtaserver.core/gtaserver.core.xproj
@@ -0,0 +1,18 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ ba69f132-3891-4c04-8e54-8161754ebdc6
+ GTAServer
+ .\obj
+ .\bin\
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/gtaserver.core/project.json b/gtaserver.core/project.json
new file mode 100644
index 0000000..4f1c83a
--- /dev/null
+++ b/gtaserver.core/project.json
@@ -0,0 +1,31 @@
+{
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "debugType": "portable",
+ "emitEntryPoint": true
+ },
+ "dependencies": {
+ "Lidgren.Network.Core": "8.0.30703",
+ "Microsoft.Extensions.Logging": "1.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "1.0.0",
+ "Microsoft.Extensions.Logging.Console": "1.0.0",
+ "Microsoft.Extensions.Logging.Debug": "1.0.0",
+ "protobuf-net": "2.1.0",
+ "System.Runtime.Loader": "4.3.0",
+ "SimpleConsoleLogger": "1.0.2"
+ },
+ "frameworks": {
+ "netcoreapp1.0": {
+ "dependencies": {
+ "NETStandard.Library": "1.6.0",
+ "Microsoft.NETCore.Runtime.CoreCLR": "1.1.0",
+ "Microsoft.NETCore.App": "1.0.0"
+ }
+ }
+ },
+ "runtimes": {
+ "win7-x64": {},
+ //"win10-x64": {},
+ "ubuntu.14.04-x64": {}
+ }
+}
diff --git a/libs/Lidgren.Network.dll b/libs/Lidgren.Network.dll
deleted file mode 100644
index 6b2b09c..0000000
Binary files a/libs/Lidgren.Network.dll and /dev/null differ
diff --git a/libs/NativeUI.dll b/libs/NativeUI.dll
index b25eef0..3291b35 100644
Binary files a/libs/NativeUI.dll and b/libs/NativeUI.dll differ
diff --git a/libs/Newtonsoft.Json.dll b/libs/Newtonsoft.Json.dll
deleted file mode 100644
index d4c9037..0000000
Binary files a/libs/Newtonsoft.Json.dll and /dev/null differ
diff --git a/libs/ScriptHookV.dll b/libs/ScriptHookV.dll
new file mode 100644
index 0000000..fd77891
Binary files /dev/null and b/libs/ScriptHookV.dll differ
diff --git a/libs/ScriptHookVDotNet.dll b/libs/ScriptHookVDotNet.dll
index 15d429a..d0200b9 100644
Binary files a/libs/ScriptHookVDotNet.dll and b/libs/ScriptHookVDotNet.dll differ
diff --git a/libs/ScriptHookVDotNet.xml b/libs/ScriptHookVDotNet.xml
new file mode 100644
index 0000000..37ee474
--- /dev/null
+++ b/libs/ScriptHookVDotNet.xml
@@ -0,0 +1,1685 @@
+
+
+
+ "ScriptHookVDotNet"
+
+
+
+
+Starts an animation.
+
+ The animation dictionary.
+ The animation name.
+ Normal value is 8.0.
+ Normal value is -8.0.
+ The duration.
+ The animation flags.
+ Values are between 0.0 and 1.0.
+
+
+
+Starts an animation.
+
+ The animation dictionary.
+ The animation name.
+ Normal value is 8.0.
+ The duration.
+ The animation flags.
+
+
+
+Starts an animation.
+
+ The animation dictionary.
+ The animation name.
+
+
+Have more than one menu on the screen on the time and transition them
+
+
+The offset each menu in the stack has from the one above it
+
+
+The top left position of the current menu
+
+
+Handles when the user presses the left or right button (e.g. numpad-4 and 6)
+
+
+Handles when the user presses the up or down button (e.g. numpad-2 and 8)
+
+
+Handles when the back button is pressed (e.g. numpad-0)
+
+
+Handles when the activate button is pressed (e.g. numpad-5)
+
+
+Draw all the active UIs
+
+
+Closes all menus
+
+
+Remove the active menu from the stack, this will focus the next highest menu
+
+
+Remove a menu from the stack of active menus
+
+
+Add a menu to the stack of active menus and set it as focused
+
+
+Set by the parent so that the MenuItem can access its properties
+
+
+Called by the Menu to set this item's origin
+
+
+Called when the user changes this item (e.g. numpad-4 and 6)
+
+
+Called when the user activates this item (e.g. numpad-5)
+
+
+Called when the user deselects this item
+
+
+Called when the user selects this item
+
+
+Called when the MenuItem should be drawn with an offset
+
+
+Called when the MenuItem should be drawn
+
+
+Use Ok and Cancel instead of Yes and No
+
+
+Called when the user changes the current element (i.e. left and right)
+
+
+Called when the user changes what element is selected (i.e. up and down)
+
+
+Called when the user hits the activate button
+
+
+Called when the user hits the back button or unfocuses from this menu
+
+
+Called when the menu gains or regains focus
+
+
+Called when the menu is first added to the Viewport
+
+
+Draws the menu with an offset
+
+
+Draws the menu
+
+
+
+Determines whether the specified object instances are considered equal.
+
+
+
+
+ true if is the same instance as or
+if both are null references or if value1.Equals(value2) returns true; otherwise, false.
+
+
+
+Returns a value that indicates whether the current instance is equal to the specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns a value that indicates whether the current instance is equal to a specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns the hash code for this instance.
+
+ A 32-bit signed integer hash code.
+
+
+
+Converts the value of the object to its equivalent string representation.
+
+ The string representation of the value of this instance.
+
+
+
+Converts the matrix to an array of floats.
+
+
+
+
+Tests for inequality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has a different value than ; otherwise, false.
+
+
+
+Tests for equality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has the same value as ; otherwise, false.
+
+
+
+Scales a matrix by a given value.
+
+ The matrix to scale.
+ The amount by which to scale.
+ The scaled matrix.
+
+
+
+Scales a matrix by a given value.
+
+ The matrix to scale.
+ The amount by which to scale.
+ The scaled matrix.
+
+
+
+Multiplies two matricies.
+
+ The first matrix to multiply.
+ The second matrix to multiply.
+ The product of the two matricies.
+
+
+
+Scales a matrix by a given value.
+
+ The matrix to scale.
+ The amount by which to scale.
+ The scaled matrix.
+
+
+
+Divides two matricies.
+
+ The first matrix to divide.
+ The second matrix to divide.
+ The quotient of the two matricies.
+
+
+
+Subtracts two matricies.
+
+ The first matrix to subtract.
+ The second matrix to subtract.
+ The difference between the two matricies.
+
+
+
+Adds two matricies.
+
+ The first matrix to add.
+ The second matrix to add.
+ The sum of the two matricies.
+
+
+
+Negates a matrix.
+
+ The matrix to negate.
+ The negated matrix.
+
+
+
+Calculates the transpose of the specified matrix.
+
+ The matrix whose transpose is to be calculated.
+ The transpose of the specified matrix.
+
+
+
+Creates a translation matrix using the specified offsets.
+
+ The offset for all three coordinate planes.
+ The created translation matrix.
+
+
+
+Creates a translation matrix using the specified offsets.
+
+ X-coordinate offset.
+ Y-coordinate offset.
+ Z-coordinate offset.
+ The created translation matrix.
+
+
+
+Creates a matrix that scales along the x-axis, y-axis, and y-axis.
+
+ Scaling factor for all three axes.
+ The created scaling matrix.
+
+
+
+Creates a matrix that scales along the x-axis, y-axis, and y-axis.
+
+ Scaling factor that is applied along the x-axis.
+ Scaling factor that is applied along the y-axis.
+ Scaling factor that is applied along the z-axis.
+ The created scaling matrix.
+
+
+
+Creates a rotation matrix with a specified yaw, pitch, and roll.
+
+ Yaw around the y-axis, in radians.
+ Pitch around the x-axis, in radians.
+ Roll around the z-axis, in radians.
+ The created rotation matrix.
+
+
+
+Creates a rotation matrix from a quaternion.
+
+ The quaternion to use to build the matrix.
+ The created rotation matrix.
+
+
+
+Creates a matrix that rotates around an arbitary axis.
+
+ The axis around which to rotate.
+ Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
+ The created rotation matrix.
+
+
+
+Creates a matrix that rotates around the z-axis.
+
+ Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
+ The created rotation matrix.
+
+
+
+Creates a matrix that rotates around the y-axis.
+
+ Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
+ The created rotation matrix.
+
+
+
+Creates a matrix that rotates around the x-axis.
+
+ Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
+ The created rotation matrix.
+
+
+
+Performs a linear interpolation between two matricies.
+
+ Start matrix.
+ End matrix.
+ Value between 0 and 1 indicating the weight of .
+ The linear interpolation of the two matrices.
+
+This method performs the linear interpolation based on the following formula.
+start + (end - start) * amount
+Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned.
+
+
+
+
+Calculates the inverse of a matrix if it exists.
+
+ The inverse of the matrix.
+
+
+
+Negates a matrix.
+
+ The matrix to be negated.
+ The negated matrix.
+
+
+
+Scales a matrix by the given value.
+
+ The matrix to scale.
+ The amount by which to scale.
+ The scaled matrix.
+
+
+
+Determines the quotient of two matrices.
+
+ The first matrix to divide.
+ The second matrix to divide.
+ The quotient of the two matrices.
+
+
+
+Scales a matrix by the given value.
+
+ The matrix to scale.
+ The amount by which to scale.
+ The scaled matrix.
+
+
+
+Determines the product of two matrices.
+
+ The first matrix to multiply.
+ The second matrix to multiply.
+ The product of the two matrices.
+
+
+
+Determines the difference between two matrices.
+
+ The first matrix to subtract.
+ The second matrix to subtract.
+ The difference between the two matrices.
+
+
+
+Determines the sum of two matrices.
+
+ The first matrix to add.
+ The second matrix to add.
+ The sum of the two matrices.
+
+
+
+Calculates the inverse of the matrix if it exists.
+
+
+
+
+Calculates the determinant of the matrix.
+
+ The determinant of the matrix.
+
+
+
+Converts the matrix to an array of floats.
+
+
+
+
+Gets a value indicating whether this instance has an inverse matrix.
+
+
+
+
+Gets a value indicating whether this instance is an identity matrix.
+
+
+
+
+Gets a that represents an identity matrix.
+
+
+
+
+Gets or sets the element of the matrix that exists in the fourth row and fourth column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the fourth row and third column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the fourth row and second column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the fourth row and first column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the third row and fourth column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the third row and third column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the third row and second column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the third row and first column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the second row and fourth column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the second row and third column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the second row and second column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the second row and first column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the first row and fourth column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the first row and third column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the first row and second column.
+
+
+
+
+Gets or sets the element of the matrix that exists in the first row and first column.
+
+
+
+
+Defines a 4x4 matrix.
+
+ D3DXMATRIX
+
+
+ Gets or sets the current transition ratio of the weather.
+ A Single representing the current time ratio between 0.0f and 1.0f.
+
+
+
+Determines whether the specified object instances are considered equal.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if is the same instance as or
+if both are null references or if value1.Equals(value2) returns true; otherwise, false.
+
+
+
+Returns a value that indicates whether the current instance is equal to the specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns a value that indicates whether the current instance is equal to a specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns the hash code for this instance.
+
+ A 32-bit signed integer hash code.
+
+
+
+Converts the value of the object to its equivalent string representation.
+
+ The string representation of the value of this instance.
+
+
+
+Tests for inequality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has a different value than ; otherwise, false.
+
+
+
+Tests for equality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has the same value as ; otherwise, false.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Reverses the direction of a given vector.
+
+ The vector to negate.
+ A vector facing in the opposite direction.
+
+
+
+Subtracts two vectors.
+
+ The first vector to subtract.
+ The second vector to subtract.
+ The difference of the two vectors.
+
+
+
+Adds two vectors.
+
+ The first vector to add.
+ The second vector to add.
+ The sum of the two vectors.
+
+
+
+Returns a vector containing the largest components of the specified vectors.
+
+ The first source vector.
+ The second source vector.
+ A vector containing the largest components of the source vectors.
+
+
+
+Returns a vector containing the smallest components of the specified vectors.
+
+ The first source vector.
+ The second source vector.
+ A vector containing the smallest components of the source vectors.
+
+
+
+Returns the reflection of a vector off a surface that has the specified normal.
+
+ The source vector.
+ Normal of the surface.
+ The reflected vector.
+ Reflect only gives the direction of a reflection off a surface, it does not determine
+whether the original vector was close enough to the surface to hit it.
+
+
+
+Calculates the dot product of two vectors.
+
+ First source vector.
+ Second source vector.
+ The dot product of the two vectors.
+
+
+
+Converts the vector into a unit vector.
+
+ The vector to normalize.
+ The normalized vector.
+
+
+
+Performs a linear interpolation between two vectors.
+
+ Start vector.
+ End vector.
+ Value between 0 and 1 indicating the weight of .
+ The linear interpolation of the two vectors.
+
+This method performs the linear interpolation based on the following formula.
+start + (end - start) * amount
+Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned.
+
+
+
+
+Restricts a value to be within a specified range.
+
+ The value to clamp.
+ The minimum value.
+ The maximum value.
+ The clamped value.
+
+
+
+Reverses the direction of a given vector.
+
+ The vector to negate.
+ A vector facing in the opposite direction.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Modulates a vector by another.
+
+ The first vector to modulate.
+ The second vector to modulate.
+ The modulated vector.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Subtracts two vectors.
+
+ The first vector to subtract.
+ The second vector to subtract.
+ The difference of the two vectors.
+
+
+
+Adds two vectors.
+
+ The first vector to add.
+ The second vector to add.
+ The sum of the two vectors.
+
+
+
+Returns a new normalized vector with random X and Y components.
+
+
+
+
+Converts a vector to a heading.
+
+
+
+
+Returns the signed angle in degrees between from and to.
+
+
+
+
+Returns the angle in degrees between from and to.
+The angle returned is always the acute angle between the two vectors.
+
+
+
+
+Calculates the squared distance between two vectors.
+
+ The first vector to calculate the squared distance to the second vector.
+ The second vector to calculate the squared distance to the first vector.
+ The squared distance between the two vectors.
+
+
+
+Calculates the distance between two vectors.
+
+ The first vector to calculate the distance to the second vector.
+ The second vector to calculate the distance to the first vector.
+ The distance between the two vectors.
+
+
+
+Calculates the squared distance between two vectors.
+
+ The second vector to calculate the squared distance to.
+ The squared distance to the other vector.
+
+
+
+Calculates the distance between two vectors.
+
+ The second vector to calculate the distance to.
+ The distance to the other vector.
+
+
+
+Converts the vector into a unit vector.
+
+
+
+
+Calculates the squared length of the vector.
+
+ The squared length of the vector.
+
+
+
+Calculates the length of the vector.
+
+ The length of the vector.
+
+
+
+Returns the left vector. (-1,0)
+
+
+
+
+Returns the right vector. (1,0)
+
+
+
+
+Returns the down vector. (0,-1)
+
+
+
+
+Returns the up vector. (0,1)
+
+
+
+
+Returns a null vector. (0,0)
+
+
+
+
+Returns this vector with a magnitude of 1.
+
+
+
+
+Initializes a new instance of the class.
+
+ Initial value for the X component of the vector.
+ Initial value for the Y component of the vector.
+
+
+
+Gets or sets the Y component of the vector.
+
+ The Y component of the vector.
+
+
+
+Gets or sets the X component of the vector.
+
+ The X component of the vector.
+
+
+
+Gets or sets the steering scale.
+
+ A single between -1.0f (fully right) and 1.0f (fully left).
+
+
+
+Gets or sets the steering angle.
+
+ The steering angle in degrees.
+
+
+
+Gets the speed the wheels are spinning at
+
+ The speed in meters per second
+
+
+ Can be broken into the car. if the glass is broken, the value will be set to 1.
+
+
+ Doesn't allow players to exit the vehicle with the exit vehicle key.
+
+
+
+Determines whether the specified object instances are considered equal.
+
+
+
+
+ true if is the same instance as or
+if both are null references or if value1.Equals(value2) returns true; otherwise, false.
+
+
+
+Returns a value that indicates whether the current instance is equal to the specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns a value that indicates whether the current instance is equal to a specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns the hash code for this instance.
+
+ A 32-bit signed integer hash code.
+
+
+
+Converts the value of the object to its equivalent string representation.
+
+ The string representation of the value of this instance.
+
+
+
+Tests for inequality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has a different value than ; otherwise, false.
+
+
+
+Tests for equality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has the same value as ; otherwise, false.
+
+
+
+Reverses the direction of a given quaternion.
+
+ The quaternion to negate.
+ A quaternion facing in the opposite direction.
+
+
+
+Subtracts two quaternions.
+
+ The first quaternion to subtract.
+ The second quaternion to subtract.
+ The difference of the two quaternions.
+
+
+
+Adds two quaternions.
+
+ The first quaternion to add.
+ The second quaternion to add.
+ The sum of the two quaternions.
+
+
+
+Divides a quaternion by another.
+
+ The first quaternion to divide.
+ The second quaternion to divide.
+ The divided quaternion.
+
+
+
+Scales a quaternion by the given value.
+
+ The quaternion to scale.
+ The amount by which to scale the quaternion.
+ The scaled quaternion.
+
+
+
+Scales a quaternion by the given value.
+
+ The quaternion to scale.
+ The amount by which to scale the quaternion.
+ The scaled quaternion.
+
+
+
+Rotates the point with rotation.
+
+ The quaternion to rotate the vector.
+ The vector to be rotated.
+ The vector after rotation.
+
+
+
+Multiplies a quaternion by another.
+
+ The first quaternion to multiply.
+ The second quaternion to multiply.
+ The multiplied quaternion.
+
+
+
+Subtracts two quaternions.
+
+ The first quaternion to subtract.
+ The second quaternion to subtract.
+ The difference of the two quaternions.
+
+
+
+Creates a quaternion given a yaw, pitch, and roll value.
+
+ The yaw of rotation.
+ The pitch of rotation.
+ The roll of rotation.
+ The newly created quaternion.
+
+
+
+Creates a quaternion given a rotation matrix.
+
+ The rotation matrix.
+ The newly created quaternion.
+
+
+
+Creates a quaternion given a rotation and an axis.
+
+ The axis of rotation.
+ The angle of rotation.
+ The newly created quaternion.
+
+
+
+Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).
+
+ Euler angles in degrees.
+
+
+
+eturns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).
+
+ X degrees.
+ Y degrees.
+ Z degrees.
+
+
+
+Returns the angle in degrees between two rotations a and b.
+
+ The first quaternion to calculate angle.
+ The second quaternion to calculate angle.
+ The angle in degrees between two rotations a and b.
+
+
+
+Converts the quaternion into a unit quaternion.
+
+ The quaternion to normalize.
+ The normalized quaternion.
+
+
+
+Reverses the direction of a given quaternion.
+
+ The quaternion to negate.
+ A quaternion facing in the opposite direction.
+
+
+
+Scales a quaternion by the given value.
+
+ The quaternion to scale.
+ The amount by which to scale the quaternion.
+ The scaled quaternion.
+
+
+
+Modulates a quaternion by another.
+
+ The first quaternion to modulate.
+ The second quaternion to modulate.
+ The modulated quaternion.
+
+
+
+Rotates a rotation from towards to.
+
+ From Quaternion.
+ To Quaternion.
+
+
+
+
+Creates a rotation which rotates from fromDirection to toDirection.
+
+
+
+
+Interpolates between two quaternions, using spherical linear interpolation. The parameter /t/ is not clamped.
+
+
+
+
+
+
+
+Interpolates between two quaternions, using spherical linear interpolation..
+
+ Start quaternion.
+ End quaternion.
+ Value between 0 and 1 indicating the weight of .
+ The spherical linear interpolation of the two quaternions.
+
+
+
+Performs a linear interpolation between two quaternion.
+
+ Start quaternion.
+ End quaternion.
+ Value between 0 and 1 indicating the weight of .
+ The linear interpolation of the two quaternions.
+
+This method performs the linear interpolation based on the following formula.
+start + (end - start) * amount
+Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned.
+
+
+
+
+Conjugates and renormalizes the quaternion.
+
+ The quaternion to conjugate and renormalize.
+ The conjugated and renormalized quaternion.
+
+
+
+Calculates the dot product of two quaternions.
+
+ First source quaternion.
+ Second source quaternion.
+ The dot product of the two quaternions.
+
+
+
+Divides a quaternion by another.
+
+ The first quaternion to divide.
+ The second quaternion to divide.
+ The divided quaternion.
+
+
+
+Adds two quaternions.
+
+ The first quaternion to add.
+ The second quaternion to add.
+ The sum of the two quaternions.
+
+
+
+Conjugates and renormalizes the quaternion.
+
+
+
+
+Conjugates the quaternion.
+
+
+
+
+Converts the quaternion into a unit quaternion.
+
+
+
+
+Calculates the squared length of the quaternion.
+
+ The squared length of the quaternion.
+
+
+
+Calculates the length of the quaternion.
+
+ The length of the quaternion.
+
+
+
+Gets the angle of the quaternion.
+
+
+
+
+Gets the axis components of the quaternion.
+
+
+
+
+Gets the identity (0, 0, 0, 1).
+
+
+
+
+Initializes a new instance of the structure.
+
+ A containing the first three values of the quaternion.
+ The W component of the quaternion.
+
+
+
+Initializes a new instance of the structure.
+
+ The X component of the quaternion.
+ The Y component of the quaternion.
+ The Z component of the quaternion.
+ The W component of the quaternion.
+
+
+
+Gets or sets the W component of the quaternion.
+
+ The W component of the quaternion.
+
+
+
+Gets or sets the Z component of the quaternion.
+
+ The Z component of the quaternion.
+
+
+
+Gets or sets the Y component of the quaternion.
+
+ The Y component of the quaternion.
+
+
+
+Gets or sets the X component of the quaternion.
+
+ The X component of the quaternion.
+
+
+
+Determines whether the specified object instances are considered equal.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if is the same instance as or
+if both are null references or if value1.Equals(value2) returns true; otherwise, false.
+
+
+
+Returns a value that indicates whether the current instance is equal to the specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns a value that indicates whether the current instance is equal to a specified object.
+
+ Object to make the comparison with.
+
+ true if the current instance is equal to the specified object; false otherwise.
+
+
+
+Returns the hash code for this instance.
+
+ A 32-bit signed integer hash code.
+
+
+
+Converts the value of the object to its equivalent string representation.
+
+ The string representation of the value of this instance.
+
+
+
+Tests for inequality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has a different value than ; otherwise, false.
+
+
+
+Tests for equality between two objects.
+
+ The first value to compare.
+ The second value to compare.
+
+ true if has the same value as ; otherwise, false.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Reverses the direction of a given vector.
+
+ The vector to negate.
+ A vector facing in the opposite direction.
+
+
+
+Subtracts two vectors.
+
+ The first vector to subtract.
+ The second vector to subtract.
+ The difference of the two vectors.
+
+
+
+Adds two vectors.
+
+ The first vector to add.
+ The second vector to add.
+ The sum of the two vectors.
+
+
+
+Returns a vector containing the largest components of the specified vectors.
+
+ The first source vector.
+ The second source vector.
+ A vector containing the largest components of the source vectors.
+
+
+
+Returns a vector containing the smallest components of the specified vectors.
+
+ The first source vector.
+ The second source vector.
+ A vector containing the smallest components of the source vectors.
+
+
+
+Returns the reflection of a vector off a surface that has the specified normal.
+
+ The vector to project onto the plane.
+ Normal of the surface.
+ The reflected vector.
+ Reflect only gives the direction of a reflection off a surface, it does not determine
+whether the original vector was close enough to the surface to hit it.
+
+
+
+Projects a vector onto a plane defined by a normal orthogonal to the plane.
+
+ The vector to project.
+ Normal of the plane, does not assume it is normalized.
+ The Projection of vector onto plane.
+
+
+
+Projects a vector onto another vector.
+
+ The vector to project.
+ Vector to project onto, does not assume it is normalized.
+ The projected vector.
+
+
+
+Calculates the cross product of two vectors.
+
+ First source vector.
+ Second source vector.
+ The cross product of the two vectors.
+
+
+
+Calculates the dot product of two vectors.
+
+ First source vector.
+ Second source vector.
+ The dot product of the two vectors.
+
+
+
+Converts the vector into a unit vector.
+
+ The vector to normalize.
+ The normalized vector.
+
+
+
+Performs a linear interpolation between two vectors.
+
+ Start vector.
+ End vector.
+ Value between 0 and 1 indicating the weight of .
+ The linear interpolation of the two vectors.
+
+This method performs the linear interpolation based on the following formula.
+start + (end - start) * amount
+Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned.
+
+
+
+
+Restricts a value to be within a specified range.
+
+ The value to clamp.
+ The minimum value.
+ The maximum value.
+ The clamped value.
+
+
+
+Reverses the direction of a given vector.
+
+ The vector to negate.
+ A vector facing in the opposite direction.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Modulates a vector by another.
+
+ The first vector to modulate.
+ The second vector to modulate.
+ The modulated vector.
+
+
+
+Scales a vector by the given value.
+
+ The vector to scale.
+ The amount by which to scale the vector.
+ The scaled vector.
+
+
+
+Subtracts two vectors.
+
+ The first vector to subtract.
+ The second vector to subtract.
+ The difference of the two vectors.
+
+
+
+Adds two vectors.
+
+ The first vector to add.
+ The second vector to add.
+ The sum of the two vectors.
+
+
+
+Returns a new normalized vector with random X, Y and Z components.
+
+
+
+
+Returns a new normalized vector with random X and Y components.
+
+
+
+
+Creates a random vector inside the circle around this position.
+
+
+
+
+Converts a vector to a heading.
+
+
+
+
+Returns the signed angle in degrees between from and to.
+
+
+
+
+Returns the angle in degrees between from and to.
+The angle returned is always the acute angle between the two vectors.
+
+
+
+
+Calculates the squared distance between two vectors, ignoring the Z-component.
+
+ The first vector to calculate the squared distance to the second vector.
+ The second vector to calculate the squared distance to the first vector.
+ The squared distance between the two vectors.
+
+
+
+Calculates the distance between two vectors, ignoring the Z-component.
+
+ The first vector to calculate the distance to the second vector.
+ The second vector to calculate the distance to the first vector.
+ The distance between the two vectors.
+
+
+
+Calculates the squared distance between two vectors.
+
+ The first vector to calculate the squared distance to the second vector.
+ The second vector to calculate the squared distance to the first vector.
+ The squared distance between the two vectors.
+
+
+
+Calculates the distance between two vectors.
+
+ The first vector to calculate the distance to the second vector.
+ The second vector to calculate the distance to the first vector.
+ The distance between the two vectors.
+
+
+
+Calculates the squared distance between two vectors, ignoring the Z-component.
+
+ The second vector to calculate the squared distance to.
+ The distance to the other vector.
+
+
+
+Calculates the distance between two vectors, ignoring the Z-component.
+
+ The second vector to calculate the distance to.
+ The distance to the other vector.
+
+
+
+Calculates the squared distance between two vectors.
+
+ The second vector to calculate the distance to.
+ The distance to the other vector.
+
+
+
+Calculates the distance between two vectors.
+
+ The second vector to calculate the distance to.
+ The distance to the other vector.
+
+
+
+Converts the vector into a unit vector.
+
+
+
+
+Calculates the squared length of the vector.
+
+ The squared length of the vector.
+
+
+
+Calculates the length of the vector.
+
+ The length of the vector.
+
+
+
+Returns the relative Bottom vector as used. (0,0,-1)
+
+
+
+
+Returns the relative Top vector. (0,0,1)
+
+
+
+
+Returns the relative Back vector. (0,-1,0)
+
+
+
+
+Returns the relative Front vector. (0,1,0)
+
+
+
+
+Returns the relative Left vector. (-1,0,0)
+
+
+
+
+Returns the relative Right vector. (1,0,0)
+
+
+
+
+Returns the world West vector. (-1,0,0)
+
+
+
+
+Returns the world East vector. (1,0,0)
+
+
+
+
+Returns the world South vector. (0,-1,0)
+
+
+
+
+Returns the world North vector. (0,1,0)
+
+
+
+
+Returns the world Down vector. (0,0,-1)
+
+
+
+
+Returns the world Up vector. (0,0,1)
+
+
+
+
+Returns a null vector. (0,0,0)
+
+
+
+
+Returns this vector with a magnitude of 1.
+
+
+
+
+Initializes a new instance of the class.
+
+ Initial value for the X component of the vector.
+ Initial value for the Y component of the vector.
+ Initial value for the Z component of the vector.
+
+
+
+Gets or sets the Z component of the vector.
+
+ The Z component of the vector.
+
+
+
+Gets or sets the Y component of the vector.
+
+ The Y component of the vector.
+
+
+
+Gets or sets the X component of the vector.
+
+ The X component of the vector.
+
+
+
\ No newline at end of file
diff --git a/libs/dinput8.dll b/libs/dinput8.dll
new file mode 100644
index 0000000..3e67752
Binary files /dev/null and b/libs/dinput8.dll differ
diff --git a/libs/geoip.mmdb b/libs/geoip.mmdb
new file mode 100644
index 0000000..7c494a6
Binary files /dev/null and b/libs/geoip.mmdb differ
diff --git a/libs/protobuf-net.dll b/libs/protobuf-net.dll
deleted file mode 100644
index de4701c..0000000
Binary files a/libs/protobuf-net.dll and /dev/null differ
diff --git a/lidgren.network b/lidgren.network
new file mode 160000
index 0000000..b53c3ef
--- /dev/null
+++ b/lidgren.network
@@ -0,0 +1 @@
+Subproject commit b53c3ef2b546e83bc91636bc3e83230bc3d96a97