Git Product home page Git Product logo

riders.tweakbox's Introduction

Tweakbox for Sonic Riders


โ›ธ Catch me if you can ๐Ÿ›น

All in one mod for Sonic Riders PC. Also known as the "Netplay Mod".

Note

This project is a "work in progress"; while it is usable/playable, I have high personal quality standards and don't yet consider this project "ready for public consumption" at this moment in time. Tread at your own risk.

For more information, please visit the documentation, it's cool.

Features

โœ” Fully Implemented & Reliably Working
โš  Work in Progress / Has Issues
โŒ Not Yet Implemented
๐Ÿ’ข Not Yet Implemented (Low Priority)

๐ŸŒ Netplay / Online Multiplayer

๐Ÿš€ General Features

โœ” Single-Screen Mode
โœ” Split-Screen Mode
โœ” Spectator Mode
โœ” Multiplayer Online
โœ” Custom Jitter Buffer (Reduced Player Stuttering)
โœ” NAT Punching (No Port Forwarding Required)
โœ” Server Browser
โœ” Texture Injection
โœ” Music Injection
๐Ÿ’ข Custom Game Modes (Relay, Hide & Seek)

๐Ÿ’ซ Menu Synchronization

โœ” Stage Select Menu
โœ” Character Select Menu
โœ” Race Settings Menu
โœ” Return Straight to Stage Select Post Race
โœ” Disconnect Clients Leaving Stage Select Post Race\

๐Ÿ’ฅ In-Race

โœ” Accurate Physics (Speed, Rotation, Position, Turning, AnalogInput)
โœ” Accurate Attacks (Client-Side)
โœ” Accurate Race Start Time (~1 frame difference)
โœ” Player State
โœ” Game Data (Custom Gears/Physics)
โœ” Lap Counter
โœ” Race Finish Time
โœ” Skip Intro Cutscene
โœ” Control Player Post Race Finish (It's Funny!)\

โš  Random Number Generator (Desyncs in single-screen mode due to off-screen objects seeding RNG.)
โš  Separate Item Random Number Generator (Can desync on extremely unstable connections.)\

โœ” Pauseless Pause Menu
โœ” Post-Race Pause/Results Menu Synchronization
โŒ Ramp/Trick Synchronization
๐Ÿ’ข Player Indicators in Split Screen
๐Ÿ’ข Player Indicators for 5P/6P/7P/8P
๐Ÿ’ข Lap Timer Synchronization
๐Ÿ’ข Battle Mode Spawn Synchronization
๐Ÿ’ข Battle Mode Health Synchronization
๐Ÿ’ข Movement Extrapolation (Roll-forward/Real-time prediction of player position)

๐Ÿ›‘ Anti-Cheat

An optional feature for when things become more stable...

๐Ÿ’ข Anti Lap Counter Manipulation
๐Ÿ’ข Anti Ring Counter Manipulation
๐Ÿ’ข Anti Teleport
๐Ÿ’ข Anti Gear & Physics Data Manipulation
๐Ÿ’ข Anti Speed Hack
๐Ÿ’ข Anti RNG Unrandomizer

Graphics

โœ” Use Direct3D 9Ex Renderer (better fullscreen, performance gains)
โœ” Fixed Performance Issues on Multi-core Systems
โœ” Fixed Frame Pacing (no more micro-stutters)
โœ” Borderless Windowed
โœ” Custom Resolution
โœ” Toggle Blur
โš  Dynamic Widescreen Hack (WIP, Suggest using GameMasterPlc's Widescreen EXE in the Meantime)

Editors

โœ” Gear Editor
โœ” Physics Editor

  • โœ” Running Physics
  • โœ” Character Type Stats

Gameplay

โœ” Simulate Keyboard QTE Bug
โœ” Force Single Player Stages
โœ” Force Single Player Models

Miscellaneous

โœ” Boot to Menu
โœ” Unlock All
โœ” Import Gear Data from Dolphin Emulator (GameCube Version)
โœ” Various Debug Tools

riders.tweakbox's People

Contributors

sewer56 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

riders.tweakbox's Issues

Synchronization of Race Start Times

The Wait Signal

Game execution pauses when the initial stage intro cutscene is skipped by any user.

If the player is a host:

  • Wait for all clients.
  • Send resume signal.

If the player is a client:

  • Send ready signal.
  • Wait for resume signal.

Skipping of the cutscene should be synchronized if possible but it's optional.
At this current time it requires more reverse engineering.

The Resume Signal

One method of implementing resuming after all players are ready would be to simply have the host send a "ready" signal to the player and everyone would resume game immediately. This is naive and would create a host advantage.

Instead, we are going to do the following:

  • X: Host calculates highest ping of all players and doubles it.
  • Y: Host calculates time from now (in UTC) + X.
  • Host sends Y to players. Host and players spin the thread waiting until time is later than Y.
  • Everyone resumes the game.

Netplay start an race sync don't work.

After pressing Start an Race the game will not tell the other player that the game is starting resulting an DC.

If you try to start at the same time it will throw out an netplay error but will continue until somebody cross the starting line resulting player 2 to crash.

Note about the crash: this could crash everyone expect the host.

[Bug] Items running on a cycle Desync due to inconsistent cutscene skip time.

Objects in the game world which run on a cycle may be desynced during Netplay sessions because players receive the skip intro message at different times.

Potential Solutions

Fast Restart Stage & Frame 1 Skip

Possibly the fastest solution given how cheap restarts are.

Fast Restart is also already implemented at ObjectLayoutController.
All you would have to do is flip the _skipRequested flag in RaceIntroSync.cs.

Synchronizing time post restart might be a concern, however this is currently handled by the RNG synchronizer (Random.cs). However, you would need to rewire the hook calling OnRaceSkipIntro to distinguish between a skip and normal start. In addition, screen face-in effect would need to be removed.

Note: Saying "Skip at Frame X" is illegal, because a player might receive the message late.

Disable the Intro Cutscene Skip Button.

An extremely simple but effective solution.
But also might annoy players.

Non-solutions

Reload Object Layout

This is currently a non-solution as I do not know how to unload the collision from objects.

Synchronization of RNG

In order to maintain consistency between players, the random number generator will require synchronizing.

Initial Synchronization

Initial synchronization should be performed by hooking the native srand function that has been inlined into the executable. It is available at 0x0059B7BD.

srand() is called on:

  • Race load start.
  • Race start (after intro cutscene).
  • Race restart.

Since srand is only called during initialization, the host should send out a seed to the players every time the function is called and wait for acknowledgements (effectively freeze the game). Players should wait for an acknowledgement from the host.

Constant Synchronization

While initial synchronization should maintain perfect synchronization in theory; in practice there are still edge cases such as a client disconnecting, grabbing an item box and reconnecting.

Other cases include RNG triggering events that may not be hooked by the user.
In order to enforce a consistent RNG for those edge cases, the client's seeds should simply force synchronize with the host in a non-blocking way.

During gameplay, after the host executes the rand function, the host should send a copy of the new seed using the reliable channel. Clients will apply this new seed asynchronously.

rand() is called on:

  • Periodically on a timer.
  • On item pickup.
  • On other similar conditions.

Address of rand: 0x0059B7CA

Question / Potential Suggestion idk

Is there a way to disable the Unlock All feature? Like, is it temporary? And also, when you use Tweakbox, is everything unlocked by default? Sorry, I've not tried it yet.

Reminder: Disable DX9 PXGP Threading To Fix CPU Affinity Problem (Low Framerates)

Code:

FixesController:

var _dx9Hook = new DX9Hook(SDK.ReloadedHooks);
var  _createDeviceHook = _dx9Hook.Direct3D9VTable.CreateFunctionHook<DX9Hook.CreateDevice>((int)IDirect3D9.CreateDevice, CreateDevideHook).Activate();
private IntPtr CreateDevideHook(IntPtr direct3dpointer, uint adapter, DeviceType devicetype, IntPtr hfocuswindow, CreateFlags behaviorflags, ref PresentParameters ppresentationparameters, int** ppreturneddeviceinterface)
{
    behaviorflags &= ~CreateFlags.Multithreaded;
    behaviorflags |= CreateFlags.DisablePsgpThreading;
    return _createDeviceHook.OriginalFunction(direct3dpointer, adapter, devicetype, hfocuswindow, behaviorflags, ref ppresentationparameters, ppreturneddeviceinterface);
}

Anti-Cheat: Anti-Speedhack

About Speedhacks

We should detect for Speedhacks as accurately as possible, as changes in speed can be made subtle (e.g. 105%).

Offending Functions

Speed hack implementations typically hook the following functions:

  • QueryPerformanceCounter
  • GetTickCount
  • TimeGetTime

In our case of Sonic Riders, frame pacing is probably performed using the function at 0x00527CE0 and the API function used is GetTickCount.

Detecting Speedup

To detect speedup of a client, perform 2 checks:

  • Server-side Time Check
    • Use APIs not touched by common speed hacks e.g. GetSystemTime
  • Server-side Message Arrival Check
    • Compare arrival times between messages.

The frame pacing function should be hooked. Every 5 seconds (300 frames), the client should send a ping to the server. This will occur faster if speedhack is used.

The ping should contain a timestamp with the current date/time (from GetSystemTime (unaffected by speed hacks)) and the amount of frames since the last ping (affected by speed hacks).

struct TimeStamp
{
    DateTime dateTime;
    short framesElapsed;
}

The server can then perform the following checks:

  • ToRealTime(framesElapsed) < SystemTime = Player is Cheating. (1% Error Margin)
  • Current Message Arrival - Last Message Arrival < 5 seconds (5% Error Margin + PingOfClient)

Assume cheating if no messages received at all from client.

Detecting Common Implementations

Cheat Engine

Check if module speedhack-i386.dll is loaded into the process.
Raise flag if present.

Bug: I changed some settings, and now it crashes when trying to start it!

The settings I changed were "Boot to Menu and Unlock All" to false, and all the "Boot to stage selection after completing ___." options, and now upon attempting to open the game, it simply does not work, also, when going into fullscreen, I have to click somewhere else for the game to think my cursor is on one of the options, please help! I really wanted to try this out! Here are my settings from the configuration / fixesConfiguration text file.
image

When I go on Sonic Riders using Tweakbox, it doesn't let me click on anything in the game

Rather it just focuses on the console, I can tell it does this because my mouse lets me adjust the window size of the console while ingame. It makes it not possible to click on any of the options, making the tweakbox practically unusable, I tried reporting on this issue a long while bag, but you had just closed it without any explanation on how to fix my problem. Please help when you can!

Implementation: Pauseless Pause Menu

A Pauseless Pause Menu

While syncing pause between 8 players might be appropriate, it doesn't hold up between 8 when people can troll (especially people you don't know). In practice, it might be better and easier to keep the game running.

How to Implement

The game has a pause flag at 0x00696C28 which pretty much controls more-less everything.
What we would need to do is replace all uses of the flag in the context of the pause menu with our own flag.

To do this, use a Reloaded.Memory Pinnable<T> with some mid-function ASM hooks to instead check against our own flag, which will be toggled when the game is paused. (Old flag will remain unchanged across pausing).

Injection Points

Enable Pause Menu Task/Controller: 004321F5
Disable Pause Menu Task/Controller: 00434990

Replace references to isPaused (0x00696C28) with our own.

To Do

  • Investigate Disabling Restart.

Miscellaneous Reminders

Frame pacing function: 0x00527CE0
Edit: And maybe sync race settings on connect to host. (005F8758)

// TODO: For mid-race disconnection support.
//       Switch player to BOT if player disconnects.
//       Send BOT Data.
//       Stop syncing BOT data on return to menu.

//       Client: Set join/reset flag on member disconnect.
//       Character Select: If join/reset flag is set, reset the character selection.

Anti-Cheat: Anti-Teleport

Simple Anti Teleport

Assume player can have a maximum speed of ~540 (2.5 float).
Assume a fixed time interval between frames of 16.66 ms.

Calculate distance travelled between two previous frames from player.
Calculate time between two received packets.

Perform Speed = Distance / Time and compare against maximum speed, 5.0 float.
If speed is higher, assume teleport happened.
Do not raise cheat message in case of packet loss. Instead, teleport player back to previous frame.

Ignore if player state is Auto Section or Shortcut.

About Anti-Cheat

Goal

To develop a basic Anti-Cheat with basic verification of consistent game state. The goal is mainly to stop 'script-kiddies' as opposed to programmers or hackers; validation should be done server-side.

Since the mod is open source and based off of IL bytecode which is easy to decompile; stopping programmers or hackers from cheating is not the goal; only the most basic of people.

Properties

  • Anti-Cheat should be optional (host toggled).
    • For fun and a deterrent for distributing hacked clients.
  • Client should know if Anti-Cheat is enabled.

Examples

The following are examples of the kinds of cheats I would like to prevent:

  • Modifying Gear Stats (Integrity)
  • Modifying Physics (Integrity)
  • Teleporting
  • Speed Hack (in particular, Cheat Engine)
  • RNG: Copy and write back current RNG value before seeding. Helps against freezing in CE.

Important Note

Anti-Cheat should be customizable by external mods and account for any logic changes introduced by them.

Synchronization of Game Data

Introduction

As both a basic anti-cheating measure and a basic measure to help detect bugs (inconsistencies) in mods sitting ontop of the netplay layer; the netplay implementation should ensure that known reverse engineered constants match between players at the start of the race.

Things to Synchronize

When to Validate

Perform the hash check in the same step as waiting for other players after skipping of the intro cutscene (as part of #3). Hash check is mandatory and should be done using TCP.

Hashing Algorithm

Although the data to be hashed will be small, we should preferably use a fast hashing algorithm.
The algorithm doesn't necessarily need to be cryptographic, just provide reasonable collision resistance.

The performance driven xxHash should suffice: https://github.com/uranium62/xxHash

Game doesn't start with Tweakbox enabled

When I enable tweakbox, the command line window display an error message and then close, the game doesn't start.
This mod works on my other two computers, but not on my main one

.NET 8.0.6 x86/x64 installed
Reloaded-II 1.27.10
Tweakbox 0.7.1

Error message:
Fatal error. Invalid Program: attempted to call a UnmanagedCallersOnly method from managed code.
Fatal error while logging another fatal error.
Fatal error while logging another fatal error.

Anti-Cheat: Player Stats

Cheating in Race Initialization

There should be a basic check for player initialisation during the start of the race.
The goal here is to detect basic usage of trainers and frozen values in Cheat-Engine.

The following values should be checked:

  • Player Ring Count (watch out for Ring Gears)
  • Player Lap Counter

Active Monitoring

  • Player Drift Frame Counter
  • Player Boost Frame Counter

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.