mirror of
https://github.com/djdevin/recflare-client.git
synced 2026-09-08 06:31:28 -07:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| beff81ced6 | |||
| 4c7a243549 | |||
| e512b81145 | |||
| ea33c3332e | |||
| 9ae10ce4b7 | |||
| 647d43e545 | |||
| b7e516adea | |||
| 95f309c342 | |||
| 7d40a5e116 | |||
| 0ee5735564 | |||
| 87a1b229bc | |||
| 4407f31bae | |||
| ef13dbd6c1 | |||
| 6be7b498ee |
@@ -4,3 +4,5 @@
|
||||
!RecRoom_Data/il2cpp_data/Metadata/global-metadata.zip
|
||||
!RecRoomVR.bat
|
||||
!RecRoomScreen.bat
|
||||
!RecFlareSetup.iss
|
||||
!icon.ico
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
## Allows other fields below in the advanced section to be modified.
|
||||
# Setting type: Boolean
|
||||
# Default value: false
|
||||
Enabled Advanced Settings = false
|
||||
Enabled Advanced Settings = true
|
||||
|
||||
## Custom Photon NameServer
|
||||
# Setting type: String
|
||||
# Default value:
|
||||
Photon NameServer =
|
||||
Photon NameServer = photon.recflare.net
|
||||
|
||||
## Custom Photon NameServer Port (if 0, it will be default)
|
||||
# Setting type: Int32
|
||||
# Default value: 0
|
||||
Photon NameServer Port = 0
|
||||
Photon NameServer Port = 5058
|
||||
|
||||
## Show debug logs (HTTP tracing, etc. WARNING: will include sensitive information such as passwords and auth tokens in the logs, be careful when sharing them!)
|
||||
# Setting type: Boolean
|
||||
@@ -58,17 +58,17 @@ DeviceId Response Status = 200
|
||||
## Photon Realtime App ID
|
||||
# Setting type: String
|
||||
# Default value:
|
||||
App Id Realtime = 8f322bdb-2b1f-4c27-a232-01436f43d14e
|
||||
App Id Realtime = rf-8f322bdb
|
||||
|
||||
## Photon Voice App ID
|
||||
# Setting type: String
|
||||
# Default value:
|
||||
App Id Voice = 6b4682e1-a1a9-4e04-b44a-6db0049a4df3
|
||||
App Id Voice = rf-6b4682e1
|
||||
|
||||
## Photon Chat App ID
|
||||
# Setting type: String
|
||||
# Default value:
|
||||
App Id Chat = 55fae86e-0459-4f97-bf6c-39c9341da6ef
|
||||
App Id Chat = rf-55fae86e
|
||||
|
||||
[Server]
|
||||
|
||||
@@ -77,3 +77,15 @@ App Id Chat = 55fae86e-0459-4f97-bf6c-39c9341da6ef
|
||||
# Default value: https://ns.rec.net
|
||||
RecNet NameServer Host = https://ns.recflare.net
|
||||
|
||||
[Signing]
|
||||
|
||||
## Force RSA signature verification to succeed (ON by default), so the client stops checking that images are signed with Rec Room's private key. This is what lets a self-hosted server serve its own images without the baked-in modulus matching. Set false only if you actually want signed images, in which case use 'Signing Modulus Override' instead. NOTE: this forces ALL mscorlib RSA verification to pass, not just image signatures.
|
||||
# Setting type: Boolean
|
||||
# Default value: true
|
||||
Disable Signature Verification = true
|
||||
|
||||
## Optional alternative to disabling verification: your own RSA public modulus, base64, RAW 2048-bit (256 bytes decoded) — NOT a PEM/DER key. When set, it is substituted for the modulus baked into global-metadata.dat and real verification still runs, so images stay signed with your keypair. Redundant while 'Disable Signature Verification' is true. Empty = leave the stock modulus alone.
|
||||
# Setting type: String
|
||||
# Default value:
|
||||
Signing Modulus Override =
|
||||
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
# RecFlare client
|
||||
# RecFlare game client
|
||||
|
||||
Autoamtic setup of the game client to connect to the testing [RecFlare](https://github.com/djdevin/recflare) instance.
|
||||
Automatic download and setup of a game client to play [RecFlare](https://github.com/djdevin/recflare).
|
||||
|
||||
## Download
|
||||
[BepInEx](https://github.com/BepInEx/BepInEx) and the [RecNet Plugin](https://github.com/djdevin/recnet-plugin) are installed as part of the setup.
|
||||
|
||||
Check out this repository or extract the ZIP: https://github.com/djdevin/recflare-client/archive/refs/heads/master.zip
|
||||
## Download/update and play
|
||||
|
||||
## Installing
|
||||
### Easy way: installer
|
||||
|
||||
1. Run `download.bat`. The script will download the game client from Steam and apply patches and configuration.
|
||||
2. Run `RecRoomScreen.bat` or `RecRoomVR.bat`
|
||||
Download and run `RecFlareSetup.exe` from the [releases page](https://github.com/djdevin/recflare-client/releases). The wizard asks whether you have Rec Room in your Steam library: if you do, it downloads the game client from Steam (DepotDownloader, signing in with your username or a Steam mobile app QR code); if not, it downloads the game files from a mirror instead. It then installs BepInEx and the RecNet plugin, and creates Start menu/desktop shortcuts for desktop and VR mode.
|
||||
|
||||
If Windows SmartScreen shows "Windows protected your PC", click **More info** and then **Run anyway** (the installer is unsigned).
|
||||
|
||||
To build the installer yourself, compile `RecFlareSetup.iss` with [Inno Setup](https://jrsoftware.org/isinfo.php) 6.1 or later: `iscc RecFlareSetup.iss`.
|
||||
|
||||
### Manual way: scripts
|
||||
|
||||
1. Check out this repository or extract the ZIP: https://github.com/djdevin/recflare-client/archive/refs/heads/master.zip
|
||||
2. Run `download.bat`. The script will ask whether you have Rec Room in your Steam library: if you do, it downloads the game client from Steam (DepotDownloader); if not, it syncs the game files from a mirror instead. Either way it then applies patches and configuration.
|
||||
3. Run `RecRoomScreen.bat` or `RecRoomVR.bat`
|
||||
|
||||
## Custom server
|
||||
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
; RecFlare installer - GUI equivalent of download.bat.
|
||||
; Build with Inno Setup 6.1+ (https://jrsoftware.org/isinfo.php):
|
||||
; iscc RecFlareSetup.iss
|
||||
; Output: Output\RecFlareSetup.exe
|
||||
|
||||
[Setup]
|
||||
AppId={{8E1D2A7B-6C43-4F0A-9B7E-3D5F80C21A96}
|
||||
AppName=RecFlare
|
||||
AppVersion=20230414
|
||||
AppPublisher=RecFlare project
|
||||
AppSupportURL=https://github.com/djdevin/recflare
|
||||
DefaultDirName={sd}\Games\RecFlare
|
||||
PrivilegesRequired=lowest
|
||||
; tar.exe ships with Windows 10 1803+; the downloads and extraction depend on it
|
||||
MinVersion=10.0.17134
|
||||
WizardStyle=modern
|
||||
SetupIconFile=icon.ico
|
||||
UninstallDisplayIcon={app}\icon.ico
|
||||
DisableProgramGroupPage=yes
|
||||
OutputBaseFilename=RecFlareSetup
|
||||
SolidCompression=yes
|
||||
UninstallDisplayName=RecFlare
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
|
||||
|
||||
[Files]
|
||||
Source: "icon.ico"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "RecRoomScreen.bat"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "RecRoomVR.bat"; DestDir: "{app}"; Flags: ignoreversion
|
||||
; Points the client at the RecFlare server. Always overwrite so reinstalls pick
|
||||
; up server changes; to use your own instance, fork and edit this file, then
|
||||
; rebuild the installer (see README "Custom server").
|
||||
Source: "BepInEx\config\net.rec.plugin.cfg"; DestDir: "{app}\BepInEx\config"; Flags: ignoreversion
|
||||
|
||||
[Icons]
|
||||
Name: "{autoprograms}\RecFlare (Desktop mode)"; Filename: "{app}\recroom.exe"; Parameters: "+forcemode:screen"; WorkingDir: "{app}"; IconFilename: "{app}\icon.ico"
|
||||
Name: "{autoprograms}\RecFlare (VR)"; Filename: "{app}\recroom.exe"; Parameters: "+forcemode:vr"; WorkingDir: "{app}"; IconFilename: "{app}\icon.ico"
|
||||
Name: "{autodesktop}\RecFlare (Desktop mode)"; Filename: "{app}\recroom.exe"; Parameters: "+forcemode:screen"; WorkingDir: "{app}"; IconFilename: "{app}\icon.ico"; Tasks: desktopicon
|
||||
Name: "{autodesktop}\RecFlare (VR)"; Filename: "{app}\recroom.exe"; Parameters: "+forcemode:vr"; WorkingDir: "{app}"; IconFilename: "{app}\icon.ico"; Tasks: desktopicon
|
||||
|
||||
[UninstallDelete]
|
||||
; The game files are downloaded, not installed, so Inno does not track them;
|
||||
; remove the whole folder on uninstall.
|
||||
Type: filesandordirs; Name: "{app}"
|
||||
|
||||
[Code]
|
||||
const
|
||||
ClientMD5 = '4c4a94624eba99028bb36445ccb03253';
|
||||
ClientURL = 'https://s3.g.megas4.com/2koayuyiwxv4groxzwdbbxg43cwustavrkvfb/recflare/client.zip';
|
||||
DepotDownloaderURL = 'https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_3.4.0/DepotDownloader-windows-x64.zip';
|
||||
BepInExURL = 'https://github.com/BepInEx/BepInEx/releases/download/v6.0.0-pre.2/BepInEx-Unity.IL2CPP-win-x64-6.0.0-pre.2.zip';
|
||||
PluginURL = 'https://github.com/djdevin/recnet-plugin/releases/download/20230414.2/RecNetPlugin.dll';
|
||||
|
||||
var
|
||||
SourcePage: TInputOptionWizardPage;
|
||||
SteamPage: TInputQueryWizardPage;
|
||||
DownloadPage: TDownloadWizardPage;
|
||||
ReuseLocalClientZip: Boolean;
|
||||
|
||||
function UsingSteam: Boolean;
|
||||
begin
|
||||
Result := SourcePage.Values[0];
|
||||
end;
|
||||
|
||||
function OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean;
|
||||
begin
|
||||
if Progress = ProgressMax then
|
||||
Log(Format('Downloaded %s', [FileName]));
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure InitializeWizard;
|
||||
begin
|
||||
SourcePage := CreateInputOptionPage(wpSelectDir,
|
||||
'Game client source', 'Where should the game files come from?',
|
||||
'Setup needs a copy of the Rec Room game client. Pick the option that applies to you, then click Next.',
|
||||
True, False);
|
||||
SourcePage.Add('I have Rec Room in my Steam library - download it from Steam');
|
||||
SourcePage.Add('I do not have it on Steam - download from the community mirror');
|
||||
SourcePage.SelectedValueIndex := 0;
|
||||
|
||||
SteamPage := CreateInputQueryPage(SourcePage.ID,
|
||||
'Steam sign-in', 'How should the Steam download sign in?',
|
||||
'Enter your Steam username, or leave it blank to sign in by scanning a QR code with the Steam mobile app. ' +
|
||||
'A separate Steam window will open during installation to finish signing in; ' +
|
||||
'this installer never sees your password.');
|
||||
SteamPage.Add('Steam username (optional):', False);
|
||||
|
||||
DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing),
|
||||
SetupMessage(msgPreparingDesc), @OnDownloadProgress);
|
||||
end;
|
||||
|
||||
function ShouldSkipPage(PageID: Integer): Boolean;
|
||||
begin
|
||||
Result := (PageID = SteamPage.ID) and not UsingSteam;
|
||||
end;
|
||||
|
||||
function NextButtonClick(CurPageID: Integer): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
if CurPageID = wpReady then begin
|
||||
DownloadPage.Clear;
|
||||
ReuseLocalClientZip := False;
|
||||
if UsingSteam then
|
||||
DownloadPage.Add(DepotDownloaderURL, 'DepotDownloader.zip', '')
|
||||
else begin
|
||||
{ A client.zip left behind by download.bat (or a previous run) is reused
|
||||
when it matches the expected hash, like the .bat does. }
|
||||
if FileExists(ExpandConstant('{app}\client.zip')) and
|
||||
SameText(GetMD5OfFile(ExpandConstant('{app}\client.zip')), ClientMD5) then
|
||||
ReuseLocalClientZip := True
|
||||
else
|
||||
DownloadPage.Add(ClientURL, 'client.zip', '');
|
||||
end;
|
||||
DownloadPage.Add(BepInExURL, 'BepInEx.zip', '');
|
||||
DownloadPage.Add(PluginURL, 'RecNetPlugin.dll', '');
|
||||
DownloadPage.Show;
|
||||
try
|
||||
try
|
||||
DownloadPage.Download;
|
||||
if not UsingSteam and not ReuseLocalClientZip and
|
||||
not SameText(GetMD5OfFile(ExpandConstant('{tmp}\client.zip')), ClientMD5) then begin
|
||||
SuppressibleMsgBox('The downloaded game client did not match the expected checksum. ' +
|
||||
'Please run Setup again.', mbCriticalError, MB_OK, IDOK);
|
||||
Result := False;
|
||||
end;
|
||||
except
|
||||
if DownloadPage.AbortedByUser then
|
||||
Log('Download aborted by user.')
|
||||
else
|
||||
SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
|
||||
Result := False;
|
||||
end;
|
||||
finally
|
||||
DownloadPage.Hide;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SetPreparingStatus(const Msg: String);
|
||||
begin
|
||||
WizardForm.PreparingLabel.Visible := True;
|
||||
WizardForm.PreparingLabel.Caption := Msg;
|
||||
WizardForm.Refresh;
|
||||
end;
|
||||
|
||||
function ExtractZip(const ZipPath, DestDir: String): Boolean;
|
||||
var
|
||||
ResultCode: Integer;
|
||||
begin
|
||||
Result := ForceDirectories(DestDir) and
|
||||
Exec(ExpandConstant('{sys}\tar.exe'), Format('-xf "%s" -C "%s"', [ZipPath, DestDir]),
|
||||
'', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0);
|
||||
end;
|
||||
|
||||
function RunDepotDownloader(var ErrorMsg: String): Boolean;
|
||||
var
|
||||
Args: String;
|
||||
ResultCode: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
if not ExtractZip(ExpandConstant('{tmp}\DepotDownloader.zip'), ExpandConstant('{tmp}\DepotDownloader')) then begin
|
||||
ErrorMsg := 'Could not extract DepotDownloader.';
|
||||
Exit;
|
||||
end;
|
||||
Args := '-app 471710 -depot 471711 -manifest 6426603215211043630 -remember-password' +
|
||||
' -dir "' + ExpandConstant('{app}') + '"';
|
||||
if Trim(SteamPage.Values[0]) <> '' then
|
||||
Args := Args + ' -username "' + Trim(SteamPage.Values[0]) + '"'
|
||||
else
|
||||
Args := Args + ' -qr';
|
||||
SetPreparingStatus('Downloading the game from Steam - follow the sign-in steps in the window that just opened...');
|
||||
if not Exec(ExpandConstant('{tmp}\DepotDownloader\DepotDownloader.exe'), Args,
|
||||
ExpandConstant('{tmp}\DepotDownloader'), SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode)
|
||||
or (ResultCode <> 0) then begin
|
||||
ErrorMsg := 'The Steam download did not complete (exit code ' + IntToStr(ResultCode) + '). ' +
|
||||
'Check that your sign-in succeeded and that Rec Room is in your Steam library, then run Setup again.';
|
||||
Exit;
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function PrepareToInstall(var NeedsRestart: Boolean): String;
|
||||
var
|
||||
ClientZip: String;
|
||||
begin
|
||||
Result := '';
|
||||
if not ForceDirectories(ExpandConstant('{app}')) then begin
|
||||
Result := 'Could not create the installation folder.';
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if UsingSteam then begin
|
||||
if not RunDepotDownloader(Result) then
|
||||
Exit;
|
||||
end else begin
|
||||
if ReuseLocalClientZip then
|
||||
ClientZip := ExpandConstant('{app}\client.zip')
|
||||
else
|
||||
ClientZip := ExpandConstant('{tmp}\client.zip');
|
||||
SetPreparingStatus('Extracting the game client (this can take a few minutes)...');
|
||||
if not ExtractZip(ClientZip, ExpandConstant('{app}')) then begin
|
||||
Result := 'Could not extract the game client archive.';
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
SetPreparingStatus('Installing BepInEx...');
|
||||
if not ExtractZip(ExpandConstant('{tmp}\BepInEx.zip'), ExpandConstant('{app}')) then begin
|
||||
Result := 'Could not extract BepInEx.';
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not SaveStringToFile(ExpandConstant('{app}\steam_appid.txt'), '480', False) then begin
|
||||
Result := 'Could not write steam_appid.txt.';
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not ForceDirectories(ExpandConstant('{app}\BepInEx\plugins')) or
|
||||
not FileCopy(ExpandConstant('{tmp}\RecNetPlugin.dll'),
|
||||
ExpandConstant('{app}\BepInEx\plugins\RecNetPlugin.dll'), False) then begin
|
||||
Result := 'Could not install RecNetPlugin.dll.';
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
Binary file not shown.
+31
-8
@@ -8,6 +8,10 @@ set "GREEN=%ESC%[92m"
|
||||
set "RED=%ESC%[91m"
|
||||
set "RESET=%ESC%[0m"
|
||||
|
||||
choice /C YN /M "Do you have Rec Room in your Steam library? "
|
||||
if errorlevel 2 goto :bucket
|
||||
|
||||
:steam
|
||||
set "STEAM_USERNAME="
|
||||
set /p STEAM_USERNAME=Enter your Steam username:
|
||||
if "%STEAM_USERNAME%"=="" (
|
||||
@@ -16,28 +20,47 @@ if "%STEAM_USERNAME%"=="" (
|
||||
)
|
||||
|
||||
echo %CYAN%=== Installing DepotDownloader ===%RESET%
|
||||
curl -f -L -o DepotDownloader.zip https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_3.4.0/DepotDownloader-windows-x64.zip || goto :error
|
||||
curl -s -f -L -o DepotDownloader.zip https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_3.4.0/DepotDownloader-windows-x64.zip || goto :error
|
||||
if not exist "DepotDownloader" mkdir "DepotDownloader"
|
||||
tar -xf DepotDownloader.zip -C DepotDownloader || goto :error
|
||||
del DepotDownloader.zip
|
||||
|
||||
echo %CYAN%=== Downloading Rec Room depot via DepotDownloader (will prompt for Steam password) ===%RESET%
|
||||
DepotDownloader\DepotDownloader.exe -remember-password -app 471710 -depot 471711 -manifest 7859140924515540835 -dir . -username "%STEAM_USERNAME%" || goto :error
|
||||
echo %CYAN%=== Downloading depot via DepotDownloader (will prompt for Steam password) ===%RESET%
|
||||
DepotDownloader\DepotDownloader.exe -remember-password -app 471710 -depot 471711 -manifest 6426603215211043630 -dir . -username "%STEAM_USERNAME%" || goto :error
|
||||
goto :patch
|
||||
|
||||
:bucket
|
||||
set "CLIENT_MD5=4c4a94624eba99028bb36445ccb03253"
|
||||
if not exist client.zip goto :download
|
||||
echo %CYAN%=== Checking existing client.zip ===%RESET%
|
||||
set "LOCAL_MD5="
|
||||
for /f "skip=1 delims=" %%h in ('certutil -hashfile client.zip MD5') do if not defined LOCAL_MD5 set "LOCAL_MD5=%%h"
|
||||
if /i "%LOCAL_MD5%"=="%CLIENT_MD5%" (
|
||||
echo %GREEN%client.zip already matches expected hash - skipping download.%RESET%
|
||||
goto :extract
|
||||
)
|
||||
echo %RED%client.zip does not match expected hash - redownloading.%RESET%
|
||||
|
||||
:download
|
||||
echo %CYAN%=== Downloading game client from mirror ===%RESET%
|
||||
curl -f -L -o client.zip https://s3.g.megas4.com/2koayuyiwxv4groxzwdbbxg43cwustavrkvfb/recflare/client.zip || goto :error
|
||||
|
||||
:extract
|
||||
echo %CYAN%=== Extracting game client ===%RESET%
|
||||
tar -xf client.zip -C . || goto :error
|
||||
|
||||
:patch
|
||||
echo %CYAN%=== Writing steam_appid.txt ===%RESET%
|
||||
>steam_appid.txt echo 480
|
||||
|
||||
echo %CYAN%=== Downloading BepInEx and extracting to this directory ===%RESET%
|
||||
curl -f -L -o BepInEx.zip https://github.com/BepInEx/BepInEx/releases/download/v6.0.0-pre.2/BepInEx-Unity.IL2CPP-win-x64-6.0.0-pre.2.zip || goto :error
|
||||
curl -s -f -L -o BepInEx.zip https://github.com/BepInEx/BepInEx/releases/download/v6.0.0-pre.2/BepInEx-Unity.IL2CPP-win-x64-6.0.0-pre.2.zip || goto :error
|
||||
tar -xf BepInEx.zip -C . || goto :error
|
||||
del BepInEx.zip
|
||||
|
||||
echo %CYAN%=== Downloading RecNetPlugin.dll into BepInEx\plugins ===%RESET%
|
||||
if not exist "BepInEx\plugins" mkdir "BepInEx\plugins"
|
||||
curl -f -L -o "BepInEx\plugins\RecNetPlugin.dll" https://github.com/djdevin/recnet-plugin/releases/download/0.0.3/RecNetPlugin.dll || goto :error
|
||||
|
||||
echo %CYAN%=== Extracting bundled global-metadata into RecRoom_Data\il2cpp_data\Metadata ===%RESET%
|
||||
tar -xf "RecRoom_Data\il2cpp_data\Metadata\global-metadata.zip" -C "RecRoom_Data\il2cpp_data\Metadata" || goto :error
|
||||
curl -s -f -L -o "BepInEx\plugins\RecNetPlugin.dll" https://github.com/djdevin/recnet-plugin/releases/download/20230414.2/RecNetPlugin.dll || goto :error
|
||||
|
||||
echo %GREEN%=== Done ===%RESET%
|
||||
pause
|
||||
|
||||
Reference in New Issue
Block a user