mirror of
https://github.com/rfvgyhn/min-ed-launcher.git
synced 2026-02-04 07:45:34 +00:00
initial commit
This commit is contained in:
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
277
.gitignore
vendored
Normal file
277
.gitignore
vendored
Normal file
@ -0,0 +1,277 @@
|
||||
investigation/
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.vcxproj.filters
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/
|
||||
52
EdLauncher.sln
Normal file
52
EdLauncher.sln
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26124.0
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D211D925-EFF3-46D3-AC52-28CE80DEFA89}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{141F970C-8B2A-4D21-92B7-98E264DAFEB4}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "EdLauncher", "src\EdLauncher.fsproj", "{55188BBB-C5EE-403E-A006-12DEDF4B4D2F}"
|
||||
EndProject
|
||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "EdLauncher.Tests", "tests\EdLauncher.Tests.fsproj", "{BEA4B51C-5BA7-408D-A822-C5B61D103166}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{DCB76620-F400-4748-84ED-AA4DEA205281}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
README.md = README.md
|
||||
.gitignore = .gitignore
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{55188BBB-C5EE-403E-A006-12DEDF4B4D2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{55188BBB-C5EE-403E-A006-12DEDF4B4D2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{55188BBB-C5EE-403E-A006-12DEDF4B4D2F} = {D211D925-EFF3-46D3-AC52-28CE80DEFA89}
|
||||
{BEA4B51C-5BA7-408D-A822-C5B61D103166} = {141F970C-8B2A-4D21-92B7-98E264DAFEB4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Chris
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
15
src/EdLauncher.fsproj
Normal file
15
src/EdLauncher.fsproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Types.fs" />
|
||||
<Compile Include="Steam.fs" />
|
||||
<Compile Include="Settings.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
61
src/Program.fs
Normal file
61
src/Program.fs
Normal file
@ -0,0 +1,61 @@
|
||||
open System
|
||||
open System.IO
|
||||
open System.Runtime.InteropServices
|
||||
open Steam
|
||||
open Types
|
||||
open Settings
|
||||
|
||||
let log =
|
||||
let write level msg = printfn "[%s] - %s" level msg
|
||||
{ Debug = fun msg -> write "DBG" msg
|
||||
Info = fun msg -> write "INF" msg
|
||||
Warn = fun msg -> write "WRN" msg
|
||||
Error = fun msg -> write "ERR" msg }
|
||||
|
||||
let getOsIdent() =
|
||||
let platToStr plat =
|
||||
if plat = OSPlatform.Linux then "Linux"
|
||||
elif plat = OSPlatform.Windows then "Win"
|
||||
elif plat = OSPlatform.OSX then "Mac"
|
||||
elif plat = OSPlatform.FreeBSD then "FreeBSD"
|
||||
else "Unknown"
|
||||
let platform =
|
||||
[ OSPlatform.Linux; OSPlatform.Windows; OSPlatform.OSX; OSPlatform.FreeBSD ]
|
||||
|> List.pick (fun p -> if RuntimeInformation.IsOSPlatform(p) then Some p else None)
|
||||
|> platToStr
|
||||
let arch =
|
||||
match RuntimeInformation.ProcessArchitecture with
|
||||
| Architecture.Arm -> "Arm"
|
||||
| Architecture.Arm64 -> "Arm64"
|
||||
| Architecture.X64 -> "64"
|
||||
| Architecture.X86 -> "32"
|
||||
| unknownArch -> unknownArch.ToString()
|
||||
|
||||
platform + arch
|
||||
|
||||
let getUserDetails = function
|
||||
| Dev -> Ok { UserId = 12345UL; SessionToken = "DevToken" }
|
||||
| Oculus _ -> Error "Oculus not supported"
|
||||
| Frontier -> Error "Frontier not supported"
|
||||
| Steam _ ->
|
||||
use steam = new Steam(log)
|
||||
steam.Login()
|
||||
|
||||
let printInfo platform user =
|
||||
printfn "Elite: Dangerous Launcher"
|
||||
printfn "Platform: %A" platform
|
||||
printfn "OS: %s" (getOsIdent())
|
||||
match user with
|
||||
| Error msg -> printfn "User: Error - %s" msg
|
||||
| Ok user ->
|
||||
printfn "User: %u" user.UserId
|
||||
printfn "Session Token: %s" user.SessionToken
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
let settings = parseArgs log Settings.defaults [| |] //argv
|
||||
let user = getUserDetails settings.Platform
|
||||
|
||||
printInfo settings.Platform user
|
||||
|
||||
0
|
||||
35
src/Settings.fs
Normal file
35
src/Settings.fs
Normal file
@ -0,0 +1,35 @@
|
||||
module Settings
|
||||
|
||||
open Types
|
||||
open System
|
||||
|
||||
let defaults =
|
||||
{ Platform = Dev
|
||||
ProductMode = Pancake
|
||||
AutoRun = true
|
||||
AutoQuit = true
|
||||
WatchForCrashes = true
|
||||
RemoteLogging = false }
|
||||
|
||||
let parseArgs log defaults (args: string[]) =
|
||||
let getArg (flag:string) i =
|
||||
if i + 1 < args.Length && not (String.IsNullOrEmpty args.[i + 1]) && not (args.[i + 1].StartsWith '/') then
|
||||
flag.ToLowerInvariant(), Some args.[i + 1]
|
||||
else
|
||||
flag.ToLowerInvariant(), None
|
||||
args
|
||||
|> Array.mapi (fun index value -> index, value)
|
||||
|> Array.filter (fun (_, arg) -> not (String.IsNullOrEmpty(arg)))
|
||||
|> Array.fold (fun s (i, arg) ->
|
||||
match getArg arg i with
|
||||
| "/steamid", Some id -> { s with Platform = Steam id }
|
||||
| "/oculus", Some nonce -> { s with Platform = Oculus nonce }
|
||||
| "/noremotelogs", _ -> { s with RemoteLogging = false }
|
||||
| "/nowatchdog", _ -> { s with WatchForCrashes = false }
|
||||
| "/vr", _ -> { s with ProductMode = Vr }
|
||||
| "/autorun", _ -> { s with AutoRun = true }
|
||||
| "/autoquit", _ -> { s with AutoQuit = true }
|
||||
| _ ->
|
||||
log.Warn <| sprintf "Ignoring argument '%s'" arg
|
||||
s
|
||||
) defaults
|
||||
127
src/Steam.fs
Normal file
127
src/Steam.fs
Normal file
@ -0,0 +1,127 @@
|
||||
module Steam
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
open System.Runtime.InteropServices
|
||||
open Types
|
||||
|
||||
[<Literal>]
|
||||
let SteamLib =
|
||||
#if WINDOWS
|
||||
"steam_api64.dll"
|
||||
#else
|
||||
"libsteam_api.so"
|
||||
#endif
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern bool SteamAPI_Init()
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern void SteamAPI_Shutdown()
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern IntPtr SteamClient();
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern int SteamAPI_GetHSteamPipe()
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern int SteamAPI_ISteamClient_ConnectToGlobalUser(IntPtr instance, int pipe)
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern IntPtr SteamAPI_ISteamClient_GetISteamUser(IntPtr instance, int user, int pipe, string version)
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern uint64 SteamAPI_ISteamUser_GetSteamID(IntPtr instance)
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern uint32 SteamAPI_ISteamUser_GetAuthSessionTicket(IntPtr instance, byte[] buffer, uint32 size, uint32& count)
|
||||
|
||||
[<DllImport(SteamLib)>]
|
||||
extern void SteamAPI_ISteamUser_CancelAuthTicket(IntPtr instance, uint32 hTicket)
|
||||
|
||||
type SteamUser =
|
||||
{ UserId: UInt64
|
||||
SessionToken: string }
|
||||
|
||||
type Steam(log : ILog) =
|
||||
let mutable disposed = false
|
||||
let mutable initialized = false
|
||||
let mutable userHandle = IntPtr.Zero
|
||||
let mutable sessionToken = 0u
|
||||
|
||||
let cleanup disposing =
|
||||
if not disposed then
|
||||
log.Debug "Disposing Steam resources"
|
||||
disposed <- true
|
||||
|
||||
if userHandle <> IntPtr.Zero then
|
||||
log.Debug "Cancelling auth ticket"
|
||||
SteamAPI_ISteamUser_CancelAuthTicket(userHandle, sessionToken)
|
||||
|
||||
if initialized then
|
||||
log.Debug "closing steam"
|
||||
SteamAPI_Shutdown()
|
||||
|
||||
let getCurrentUserHandle() =
|
||||
let client = SteamClient()
|
||||
if client <> IntPtr.Zero then
|
||||
log.Debug "Got steam client"
|
||||
let pipe = SteamAPI_GetHSteamPipe()
|
||||
if pipe <> 0 then
|
||||
log.Debug "Got steam pipe"
|
||||
let globalUser = SteamAPI_ISteamClient_ConnectToGlobalUser(client, pipe)
|
||||
if globalUser <> 0 then
|
||||
log.Debug "Got steam global user"
|
||||
userHandle <- SteamAPI_ISteamClient_GetISteamUser(client, globalUser, pipe, "SteamUser019")
|
||||
if userHandle <> IntPtr.Zero then
|
||||
log.Debug "Got steam user"
|
||||
Some userHandle
|
||||
else None
|
||||
else None
|
||||
else None
|
||||
else None
|
||||
|
||||
let bytesToHex (bytes: byte[]) =
|
||||
bytes
|
||||
|> Array.map (fun b -> String.Format("{0:X2}", b))
|
||||
|> String.concat ""
|
||||
|
||||
let init() =
|
||||
if not <| File.Exists(SteamLib) then
|
||||
Error <| sprintf "Unable to find steam library '%s'" SteamLib
|
||||
elif SteamAPI_Init() then
|
||||
initialized <- true
|
||||
Ok ()
|
||||
else
|
||||
Error "Unable to initialize Steam"
|
||||
|
||||
member this.Login() =
|
||||
match init() with
|
||||
| Error m -> Error m
|
||||
| Ok _ ->
|
||||
let errorResult = Error "Unable to get current steam user. Make sure your Steam client is running."
|
||||
match getCurrentUserHandle() with
|
||||
| None -> errorResult
|
||||
| Some handle ->
|
||||
let userId = SteamAPI_ISteamUser_GetSteamID handle
|
||||
|
||||
if userId <> 0UL then
|
||||
let rawToken = Array.zeroCreate<byte> 1024
|
||||
let mutable count = 0u
|
||||
sessionToken <- SteamAPI_ISteamUser_GetAuthSessionTicket(handle, rawToken, 1024u, &count)
|
||||
|
||||
if sessionToken <> 0u then
|
||||
Ok { UserId = userId; SessionToken = bytesToHex rawToken }
|
||||
else errorResult
|
||||
else errorResult
|
||||
|
||||
interface IDisposable with
|
||||
member this.Dispose() =
|
||||
cleanup true
|
||||
GC.SuppressFinalize(this)
|
||||
|
||||
override this.Finalize() =
|
||||
cleanup false
|
||||
|
||||
|
||||
36
src/Types.fs
Normal file
36
src/Types.fs
Normal file
@ -0,0 +1,36 @@
|
||||
module Types
|
||||
|
||||
type ILog =
|
||||
{ Debug: string -> unit
|
||||
Info: string -> unit
|
||||
Warn: string -> unit
|
||||
Error: string -> unit }
|
||||
with static member Noop = { Debug = (fun _ -> ()); Info = (fun _ -> ()); Warn = (fun _ -> ()); Error = (fun _ -> ()) }
|
||||
type Platform =
|
||||
| Steam of string
|
||||
| Frontier
|
||||
| Oculus of string
|
||||
| Dev
|
||||
type ProductMode = Vr | Pancake
|
||||
type AutoRun = bool
|
||||
type AutoQuit = bool
|
||||
type WatchForCrashes = bool
|
||||
type RemoteLogging = bool
|
||||
type LauncherSettings =
|
||||
{ Platform: Platform
|
||||
ProductMode: ProductMode
|
||||
AutoRun: AutoRun
|
||||
AutoQuit: AutoQuit
|
||||
WatchForCrashes: WatchForCrashes
|
||||
RemoteLogging: RemoteLogging }
|
||||
type ServerStatus = Healthy
|
||||
type LocalVersion = Version
|
||||
type LauncherStatus =
|
||||
| Current
|
||||
| Supported
|
||||
| Expired
|
||||
| Future
|
||||
type ServerInfo =
|
||||
{ Status: ServerStatus}
|
||||
type User =
|
||||
{ Name: string }
|
||||
25
tests/EdLauncher.Tests.fsproj
Normal file
25
tests/EdLauncher.Tests.fsproj
Normal file
@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<GenerateProgramFile>false</GenerateProgramFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Settings.fs" />
|
||||
<Compile Include="Main.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Expecto" Version="9.0.0" />
|
||||
<PackageReference Include="Expecto.FsCheck" Version="9.0.0" />
|
||||
<PackageReference Include="FSharp.Core" Version="4.*" />
|
||||
<!-- <PackageReference Include="YoloDev.Expecto.TestSdk" Version="0.8.0" />-->
|
||||
<!-- <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.*" />-->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\src\EdLauncher.fsproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
5
tests/Main.fs
Normal file
5
tests/Main.fs
Normal file
@ -0,0 +1,5 @@
|
||||
open Expecto
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
Tests.runTestsInAssembly defaultConfig argv
|
||||
52
tests/Settings.fs
Normal file
52
tests/Settings.fs
Normal file
@ -0,0 +1,52 @@
|
||||
module Tests
|
||||
|
||||
open Expecto
|
||||
open Settings
|
||||
open Types
|
||||
|
||||
|
||||
|
||||
[<Tests>]
|
||||
let tests =
|
||||
let parse = parseArgs ILog.Noop Settings.defaults
|
||||
|
||||
testList "Parings command line arguments" [
|
||||
test "Matches /steamid id" {
|
||||
let settings = parse [| "/steamid"; "123" |]
|
||||
Expect.equal settings.Platform (Steam "123") ""
|
||||
}
|
||||
test "Ignores /steamid without id as next arg" {
|
||||
let settings = parse [| "/steamid"; "/123" |]
|
||||
Expect.equal settings.Platform Settings.defaults.Platform ""
|
||||
}
|
||||
test "Matches /oculus nonce" {
|
||||
let settings = parse [| "/oculus"; "123" |]
|
||||
Expect.equal settings.Platform (Oculus "123") ""
|
||||
}
|
||||
test "Ignores /oculus without nonce as next arg" {
|
||||
let settings = parse [| "/oculus"; "/123" |]
|
||||
Expect.equal settings.Platform Settings.defaults.Platform ""
|
||||
}
|
||||
test "Matches /noremotelogs" {
|
||||
let settings = parse [| "/noremotelogs" |]
|
||||
Expect.equal settings.RemoteLogging false ""
|
||||
}
|
||||
test "Matches /nowatchdog" {
|
||||
let settings = parse [| "/nowatchdog" |]
|
||||
Expect.equal settings.WatchForCrashes false ""
|
||||
}
|
||||
test "Matches /vr" {
|
||||
let settings = parse [| "/vr" |]
|
||||
Expect.equal settings.ProductMode Vr ""
|
||||
}
|
||||
test "Matches /autorun" {
|
||||
let settings = parse [| "/autorun" |]
|
||||
Expect.equal settings.AutoRun true ""
|
||||
}
|
||||
test "Matches /autoquit" {
|
||||
let settings = parse [| "/autoquit" |]
|
||||
Expect.equal settings.AutoQuit true ""
|
||||
}
|
||||
testProperty "Unknown arg doesn't change any values" <|
|
||||
fun (args:string[]) -> parse args = Settings.defaults
|
||||
]
|
||||
Reference in New Issue
Block a user