Skip to content

Added autologin support for CSRO (ICCGame) & fixed inventory update#17

Merged
kis1yi merged 3 commits into
Silkroad-Developer-Community:mainfrom
kis1yi:csro-inv
Jun 11, 2026
Merged

Added autologin support for CSRO (ICCGame) & fixed inventory update#17
kis1yi merged 3 commits into
Silkroad-Developer-Community:mainfrom
kis1yi:csro-inv

Conversation

@kis1yi

@kis1yi kis1yi commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

Release Notes

New Features

  • Added comprehensive support for Chinese client version with automatic system initialization and validation
  • Enhanced inventory item update synchronization for modern game versions
  • Integrated Chinese region gateway authentication system for secure login

Improvements

  • Optimized server list display for Chinese region clients

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kis1yi, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 40 minutes and 36 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 33ab6ede-62ec-4f43-9980-f2fd5ccc9376

📥 Commits

Reviewing files that changed from the base of the PR and between 7522c39 and 4add1d9.

📒 Files selected for processing (3)
  • Library/RSBot.Core/Components/ClientManager.cs
  • Library/RSBot.Core/Network/Handler/Agent/Inventory/InventoryUpdateItemResponse.cs
  • Plugins/RSBot.General/Components/ChineseGatewayLogin.cs
📝 Walkthrough

Walkthrough

This PR extends OasisBot to support Chinese game clients by adding startup binary patching, Chinese-specific gateway authentication with ticket generation and RC4 encryption, and modern protocol inventory update parsing with per-field update flags for both Chinese and other modern client variants.

Changes

Chinese client initialization and authentication

Layer / File(s) Summary
Client startup patching for Chinese clients
Library/RSBot.Core/Components/ClientManager.cs
A ChineseClientPatches lookup table defines per-version patch targets. After client creation with CREATE_SUSPENDED, the startup flow polls the suspended process, waits for expected byte patterns, applies in-memory patches relative to SroClientImageBase, and resumes the thread. Unused patch variables removed from BypassLauncherCheck.
Chinese gateway login component
Plugins/RSBot.General/Components/ChineseGatewayLogin.cs
Generates and writes verification (CRC-based username checksum) and ticket (machine hostname token + silpset file token + seed, all RC4-encrypted with "UGCKernel" key) into login packets. Includes helpers to read silpset tokens, build machine tokens with fallback hostname resolution, compute verification results, and create ticket seeds via CoCreateGuid or Guid.NewGuid.
Login and gateway packet handling
Plugins/RSBot.General/Components/AutoLogin.cs, Plugins/RSBot.General/PacketHandler/GatewayLoginRequest.cs, Plugins/RSBot.General/PacketHandler/GatewayServerListResponse.cs
AutoLogin branches for Chinese clients to invoke ticket writing before packet send. GatewayLoginRequest parses verify_result and ticket payload for Chinese clients. GatewayServerListResponse adjusts field-parsing boundary from Global to Chinese and strips #$C suffix from server names for Chinese clients.

Modern client inventory updates

Layer / File(s) Summary
Modern item update flag enum
Library/RSBot.Core/Objects/Inventory/Item/ModernItemUpdateFlag.cs
[Flags] enum backing ushort with bitmask values for RefObjID, Quantity, Durability, OptLevel, Variance, MagParams, BindingOptions, RemainTime, and ItemState (0x8000).
Modern client inventory update parsing
Library/RSBot.Core/Network/Handler/Agent/Inventory/InventoryUpdateItemResponse.cs
Invoke routes Global/RuSro clients to modern handler; reads update type/flags. For container updates (updateType == 9), resolves inventory from objectId; for item updates, reads source slot and applies fields (id, quantity, durability, opt, variance, magic options, binding options conditionally, remaining time, state) then fires OnUpdateInventoryItem event. Helpers map objectId to player/pet/fellow/growth/vehicle inventory and parse magic/binding option structures.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Silkroad-Developer-Community/OasisBot#11: Both PRs modify InventoryUpdateItemResponse.Invoke packet parsing in Library/RSBot.Core/Network/Handler/Agent/Inventory/InventoryUpdateItemResponse.cs, extending handling for different client types (GameClientType.RuSro vs modern clients).

Poem

🐰 A rabbit hops through gates of verifying lore,
With tickets sealed by cryptographic core,
Chinese clients patched in memory's deep,
While modern inventories their secrets keep—
RC4 and tokens dance in startup's flow,
And item flags like flags of fields now show! 🎫✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.03% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the two main changes: adding autologin support for CSRO (Chinese client) and fixing inventory updates. It's specific, concise, and directly related to the primary objectives of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Library/RSBot.Core/Components/ClientManager.cs`:
- Around line 169-174: The startup currently proceeds past the Chinese-client
patch window causing unpatched clients; modify ClientManager startup so that
when Game.ClientType == GameClientType.Chinese the code blocks startup until
WaitForChineseClientPatchTargets succeeds and ApplyChineseClientPatch completes,
and if WaitForChineseClientPatchTargets times out or ApplyChineseClientPatch
fails, abort startup (throw or stop further initialization) rather than
continuing. Also wrap any transient module metadata reads used by
WaitForChineseClientPatchTargets (the module enumeration / metadata access it
performs) in a short retry loop with small delays and a bounded overall timeout
to handle module-read races during unpacking, surfacing the final failure to the
startup gate so the process won’t continue with an unpatched client.

In
`@Library/RSBot.Core/Network/Handler/Agent/Inventory/InventoryUpdateItemResponse.cs`:
- Around line 155-156: The packet parsing currently skips consuming the
MagParams payload when ModernItemUpdateFlag.MagParams is set but item.Record is
null, causing subsequent reads to be misaligned; remove the item.Record guard so
that when updateFlags.HasFlag(ModernItemUpdateFlag.MagParams) is true you always
call ReadMagicOptions(packet, item) (or call a null-safe variant of
ReadMagicOptions that consumes the fields even if item.Record is null) to ensure
the wire payload is always consumed and parsing stays in sync.
- Around line 164-165: The modern-path branch in InventoryUpdateItemResponse
currently calls packet.ReadByte() when
updateFlags.HasFlag(ModernItemUpdateFlag.ItemState) and discards the value;
change this to persist the parsed state into the item's State property (e.g.,
set item.State = the byte read) so modern clients do not keep stale state—locate
the conditional using updateFlags.HasFlag(ModernItemUpdateFlag.ItemState),
replace the discarded packet.ReadByte() with reading into a local/temporary and
assigning it to item.State (matching the legacy path behavior).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 463276ad-c99f-4c02-bb8d-eecb5e9eb9cc

📥 Commits

Reviewing files that changed from the base of the PR and between dbfd590 and 7522c39.

📒 Files selected for processing (7)
  • Library/RSBot.Core/Components/ClientManager.cs
  • Library/RSBot.Core/Network/Handler/Agent/Inventory/InventoryUpdateItemResponse.cs
  • Library/RSBot.Core/Objects/Inventory/Item/ModernItemUpdateFlag.cs
  • Plugins/RSBot.General/Components/AutoLogin.cs
  • Plugins/RSBot.General/Components/ChineseGatewayLogin.cs
  • Plugins/RSBot.General/PacketHandler/GatewayLoginRequest.cs
  • Plugins/RSBot.General/PacketHandler/GatewayServerListResponse.cs

Comment on lines +169 to +174
if (Game.ClientType == GameClientType.Chinese)
{
var sroProcess = System.Diagnostics.Process.GetProcessById((int)pi.dwProcessId);
WaitForChineseClientPatchTargets(sroProcess, pi.hThread);
ApplyChineseClientPatch(sroProcess, pi);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make Chinese patch readiness a hard startup gate (and handle module-read races).

Line 169-174 always continues startup even when Line 411-415 times out, so Chinese clients can resume unpatched. Also, Line 406-409 can throw while module metadata is transiently unreadable during unpack, which can abort startup.

Suggested fix
-                WaitForChineseClientPatchTargets(sroProcess, pi.hThread);
+                if (!WaitForChineseClientPatchTargets(sroProcess, pi.hThread))
+                {
+                    Log.Error("Chinese client patch: targets were not ready before timeout.");
+                    return false;
+                }
                 ApplyChineseClientPatch(sroProcess, pi);
...
-    private static void WaitForChineseClientPatchTargets(Process process, IntPtr hThread)
+    private static bool WaitForChineseClientPatchTargets(Process process, IntPtr hThread)
     {
         const int sliceMs = 8;
         const int maxWaitMs = 5000;
...
-            if (process.HasExited)
-                return;
-
-            process.Refresh();
-
-            if (ChineseClientPatchTargetsReady(process.Handle, process.MainModule.BaseAddress.ToInt32()))
-                return;
+            if (process.HasExited)
+                return false;
+
+            try
+            {
+                process.Refresh();
+                if (ChineseClientPatchTargetsReady(process.Handle, process.MainModule.BaseAddress.ToInt32()))
+                    return true;
+            }
+            catch
+            {
+                // Module can be temporarily unreadable while unpacking; keep polling.
+            }
...
             if (sw.ElapsedMilliseconds >= maxWaitMs)
             {
                 Log.Warn("Chinese client patch: unpack timeout.");
-                return;
+                return false;
             }
         }
     }

Also applies to: 390-417

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Library/RSBot.Core/Components/ClientManager.cs` around lines 169 - 174, The
startup currently proceeds past the Chinese-client patch window causing
unpatched clients; modify ClientManager startup so that when Game.ClientType ==
GameClientType.Chinese the code blocks startup until
WaitForChineseClientPatchTargets succeeds and ApplyChineseClientPatch completes,
and if WaitForChineseClientPatchTargets times out or ApplyChineseClientPatch
fails, abort startup (throw or stop further initialization) rather than
continuing. Also wrap any transient module metadata reads used by
WaitForChineseClientPatchTargets (the module enumeration / metadata access it
performs) in a short retry loop with small delays and a bounded overall timeout
to handle module-read races during unpacking, surfacing the final failure to the
startup gate so the process won’t continue with an unpatched client.

Comment on lines +155 to +156
if (updateFlags.HasFlag(ModernItemUpdateFlag.MagParams) && item.Record != null)
ReadMagicOptions(packet, item);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Always consume MagParams when the flag is set.

Line 155 makes packet consumption depend on item.Record != null, but the magic-option payload is still present on the wire. If that guard fails, every later flagged read in this update shifts onto the wrong offset.

Suggested fix
-        if (updateFlags.HasFlag(ModernItemUpdateFlag.MagParams) && item.Record != null)
+        if (updateFlags.HasFlag(ModernItemUpdateFlag.MagParams))
             ReadMagicOptions(packet, item);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (updateFlags.HasFlag(ModernItemUpdateFlag.MagParams) && item.Record != null)
ReadMagicOptions(packet, item);
if (updateFlags.HasFlag(ModernItemUpdateFlag.MagParams))
ReadMagicOptions(packet, item);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Library/RSBot.Core/Network/Handler/Agent/Inventory/InventoryUpdateItemResponse.cs`
around lines 155 - 156, The packet parsing currently skips consuming the
MagParams payload when ModernItemUpdateFlag.MagParams is set but item.Record is
null, causing subsequent reads to be misaligned; remove the item.Record guard so
that when updateFlags.HasFlag(ModernItemUpdateFlag.MagParams) is true you always
call ReadMagicOptions(packet, item) (or call a null-safe variant of
ReadMagicOptions that consumes the fields even if item.Record is null) to ensure
the wire payload is always consumed and parsing stays in sync.

Comment on lines +164 to +165
if (updateFlags.HasFlag(ModernItemUpdateFlag.ItemState))
packet.ReadByte();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Persist the parsed item state instead of discarding it.

The legacy path writes this field into item.State, but the modern path just reads and drops it. That leaves modern clients with stale item state when ItemState is flagged.

Suggested fix
-        if (updateFlags.HasFlag(ModernItemUpdateFlag.ItemState))
-            packet.ReadByte();
+        if (updateFlags.HasFlag(ModernItemUpdateFlag.ItemState))
+            item.State = (InventoryItemState)packet.ReadByte();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (updateFlags.HasFlag(ModernItemUpdateFlag.ItemState))
packet.ReadByte();
if (updateFlags.HasFlag(ModernItemUpdateFlag.ItemState))
item.State = (InventoryItemState)packet.ReadByte();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Library/RSBot.Core/Network/Handler/Agent/Inventory/InventoryUpdateItemResponse.cs`
around lines 164 - 165, The modern-path branch in InventoryUpdateItemResponse
currently calls packet.ReadByte() when
updateFlags.HasFlag(ModernItemUpdateFlag.ItemState) and discards the value;
change this to persist the parsed state into the item's State property (e.g.,
set item.State = the byte read) so modern clients do not keep stale state—locate
the conditional using updateFlags.HasFlag(ModernItemUpdateFlag.ItemState),
replace the discarded packet.ReadByte() with reading into a local/temporary and
assigning it to item.State (matching the legacy path behavior).

@kis1yi kis1yi merged commit 796177c into Silkroad-Developer-Community:main Jun 11, 2026
2 checks passed
@kis1yi kis1yi deleted the csro-inv branch June 11, 2026 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant