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