Old School Ops

RF455-102 RF 4.55: eight siege kits (Beelzebub and the four late "Siege Kit" rows) have level 30 in gamedata; the client says 75, 80 or 100

Game data and scripts RF Online: Dragonborn v0.4.0 low · filed by cybercyber
New

Game: RF 4.55 (Dragonborn), server v0.4.0, Windows build (stock gameserver.exe, SHA-256 0b9c9099…), its gamedata_rf455.db. Client: the supported Taiwan build, RF_Online.bin SHA-256 46528aac…2bbc558 (2025-07-16), Language=Taiwan, its DataTable\Item.edf. Expected: a siege kit needs the level the client's item data gives it, which the tooltip shows as Required Level (for sklu029: 80).

Summary

  • In gamedata_rf455.db, siegekititem.m_nLevelLim is 30 for every row from 18 on. The client's own item data gives rows 22–29 levels 75, 80 or 100:
RowCodeDB nameDB m_nLevelLimClient level
22sklu023Attack Beelzebub Siege Kit3075
23sklu024Defence Beelzebub Siege Kit3075
24sklu025Siege Kit30100
25sklu026Attack Beelzebub Flame Siege Kit3075
26sklu027Defence Beelzebub Flame Siege Kit3075
27sklu028Siege Kit30100
28sklu029Siege Kit3080
29sklu030Siege Kit3080
  • In play the client enforces its own level, so a normal player can't use these kits early. Our level-46 Accretia holding sklu029 (tooltip: Required Level 80, in red) tried to go into siege mode with it and couldn't. The server's history.log shows no 1C/01 at all during that try (the last one is 21:31:20, with kit index 1), so the client refused locally and never asked the server (read from the log; the client code that refuses wasn't traced).
  • The server's own check is looser (read): it uses the DB value, so it would accept 1C/01 for these kits from level 30. Only a client that skips its local check reaches that. Crafting and upgrades also read this column on the server (below).
  • So this is a data inconsistency with low impact today, not a way to use the kits early.
  • These are the same rows your client sync already corrected for other columns (_client_synced_cells, source "RFOnline Taiwan Updated DataTable item.dat#27": m_nDurUnit, m_nSubType, m_nIconIDX, the four effects, m_nStdPrice…), but m_nLevelLim wasn't among them for this table.
  • Every other item table agrees with the client on the level limit (below), so this looks limited to these rows.

Server side (v0.4.0)

  • The check. (*Server).checkSiegeTransform 0x1409473e0 (1C/01) calls siegeKitLevelAllows 0x14094b640 (call at 0x1409477e1). It loads the kit with siegeKitField 0x14094b1c0 and compares the struct's +0x28 with progressLevel + equipLevelBonus: allowed when LevelLim <= level + bonus (cmp [rsp+0xf8], rcx, setle al at 0x14094b77f).
  • +0x28 is LevelLim: the SiegeKitField type descriptor 0x140b8e7c0 (size 0xB8) lists UsableType +0, SubType +8, Civil +0x10, DurUnit +0x20, LevelLim +0x28, UpLevelLim +0x30, …
  • It comes from the DB: gamedata.(*Data).SiegeKitByIndex 0x140538a80 runs SELECT m_nUsableTyoe, m_nSubType, m_strCivil, m_nDurUnit, m_nLevelLim, m_nUpLevelLim, … FROM siegekititem WHERE m_dwIndex = ? (string at 0x140c2a43a).
  • Crafting and upgrades read the same column through ItemEquipLevel / equipLevelOf (SELECT m_nLevelLim FROM <table> WHERE m_dwIndex = ?; callers planUpgrade, craftSuccessPercent, informCraftMastery).
  • These four functions are identical in our patched build and the stock one (gosyms.py diff).

Client side

  • The decrypted Item.edf is a chain of sections, one per item table (siege kit = section 27: 31 records of 240 bytes, each starting with its m_dwIndex). The level limit is the byte at record +0xAC. For rows 0–21 it equals the DB on every row; for rows 22–29 it holds 75, 75, 100, 75, 75, 100, 80, 80.
  • The tooltip agrees: sklu029 (row 28) shows "Required Level 80".
  • The same comparison over every item table (about 87,000 rows: armour, weapons, accessories, ammo, potions, boxes, traps, towers, unit parts…) finds only one other difference: radaritem row 6 rdetw00, DB 40, client 30. The radar query (RadarItemRecord, SELECT m_dwIndex, m_strCode, m_fActDelay, … FROM radaritem ) doesn't read the level, so that one has no effect on the server today.

Tried in game (2026-10-14, after 21:35): a level-46 Accretia couldn't go into siege mode with sklu029 (client level 80, DB 30). history.log has no 1C/01 from that try, so the client stopped it before sending; the server's check was never reached.

Suggested fix

  • Set siegekititem.m_nLevelLim for rows 22–29 to the client's values (75, 75, 100, 75, 75, 100, 80, 80), for instance by adding the column to the client sync for these rows. Then the server's check matches the client's instead of relying on it, and crafting and upgrades use the right level.
  • Optionally radaritem row 6 m_nLevelLim 40 → 30, for consistency.

Local workaround

None

Reported on version 0.4.0

Replies

Nobody has replied yet.

Sign in to comment.

Top xp sources

How xp works
Loading…

Open the full search page