SmartFoxServer 2X binary protocol implementation for Python
Project description
sfs2x-py
Pure Python implementation of the SmartFoxServer 2X binary protocol.
What is SmartFoxServer 2X?
SmartFoxServer 2X (SFS2X) is a real-time multiplayer game server used by many mobile and web games. It communicates over TCP using a custom binary protocol with its own type system (SFSObject/SFSArray), XOR obfuscation on client-to-server packets, optional zlib/zstd compression, and AES session encryption.
This library provides a complete encode/decode implementation of the SFS2X wire protocol in pure Python — useful for protocol analysis, reverse engineering, MITM proxying, and building game bots.
Features
- Full type system: All 19 SFS2X data types (NULL, BOOL, BYTE, SHORT, INT, LONG, FLOAT, DOUBLE, UTF_STRING, arrays, SFS_ARRAY, SFS_OBJECT)
- C2S/S2C packet framing: Encode and decode client-to-server and server-to-client packets
- XOR obfuscation: Rotating 4-byte XOR key derived from packet size
- Compression: zlib and zstd support for large packets
- AES session encryption: Key exchange via
/BlueBox/CryptoManager - Type-preserving decode:
decode_typed()wraps values inTypedValueto preserve wire types (BYTE vs INT) for MITM proxies - Packet builders:
make_extension_request(),make_keepalive(),parse_s2c_command()
Install
pip install sfs2x-py
Or from source:
git clone https://github.com/KeepALifeUS/sfs2x-py.git
cd sfs2x-py
pip install -e ".[dev]"
Quick Start
Encode/decode SFSObject
from sfs2x import SFSCodec, TypedValue, INT
# Encode
obj = {"username": "player1", "level": TypedValue(INT, 42)}
data = SFSCodec.encode(obj)
# Decode
decoded, consumed = SFSCodec.decode(data)
print(decoded) # {'username': 'player1', 'level': 42}
Build an extension request
from sfs2x import make_extension_request, decode_c2s_packet, TypedValue, INT
# Create a C2S packet
packet = make_extension_request(
cmd="chat.send",
params={"msg": "Hello!", "channel": TypedValue(INT, 1)},
server_id=1234,
)
# Decode it back
obj, _ = decode_c2s_packet(packet)
Decode a captured S2C packet
from sfs2x import decode_s2c_packet, parse_s2c_command
raw = bytes.fromhex("80001f...") # paste captured hex
obj, _ = decode_s2c_packet(raw)
cmd, params = parse_s2c_command(obj)
print(f"Command: {cmd}, Params: {params}")
Type-preserving decode for MITM
from sfs2x import decode_c2s_packet_typed
obj, _ = decode_c2s_packet_typed(packet)
# Values are TypedValue instances — re-encoding preserves wire types
Protocol Overview
Wire Format
S2C (server → client):
[0x80] [size: 2B BE] [SFSObject payload]
C2S (client → server):
[0xC4] [server_id: 2B BE] [size: 2B BE] [XOR-obfuscated payload]
[0xE4] [server_id: 2B BE] [size: 2B BE] [XOR(zlib(payload))] (compressed)
SFSObject Structure
The payload is always a root SFSObject with:
"c"→ controller ID (BYTE: 0=system, 1=extension)"a"→ action ID (SHORT)"p"→ parameters (SFS_OBJECT)
Extension commands (c=1, a=13) nest further:
"p"."c"→ command name (UTF_STRING)"p"."r"→ room ID (INT)"p"."p"→ command parameters (SFS_OBJECT)
API Reference
sfs2x.objects
SFSCodec.encode(obj)→bytes— Encode a dict as SFSObjectSFSCodec.decode(data)→(dict, int)— Decode SFSObject, return (dict, bytes_consumed)SFSCodec.decode_typed(data)→(dict, int)— Decode preserving wire types asTypedValueTypedValue(type_id, value)— Force a specific wire type
sfs2x.protocol
encode_c2s_packet(controller, action, params, server_id, compress)→bytesdecode_c2s_packet(data)→(dict, int)decode_c2s_packet_typed(data)→(dict, int)encode_s2c_packet(obj, compress)→bytesdecode_s2c_packet(data)→(dict, int)make_extension_request(cmd, params, room_id, server_id)→bytesmake_keepalive(client_time, server_id)→bytesparse_s2c_command(obj)→(str | None, dict)iter_s2c_packets(data)→ iterator of(dict, offset)
sfs2x.crypto
AESCipher(key, iv)— AES-128-CBC with fixed IVKeyExchange()— Manages key exchange via CryptoManager endpointmake_password_hash(session_token, password)→str— MD5 password hash
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sfs2x_py-0.1.1.tar.gz.
File metadata
- Download URL: sfs2x_py-0.1.1.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9876566130803c69344804a5c2e63a6c215a9bccac11c7196e0969b40fe3d30d
|
|
| MD5 |
73f0dc41d0c597c44275499293f7c960
|
|
| BLAKE2b-256 |
7ca60ec93d5610349355ea5375917ca44b432e6716600648a7ed3020ad33b68f
|
Provenance
The following attestation bundles were made for sfs2x_py-0.1.1.tar.gz:
Publisher:
publish.yml on KeepALifeUS/sfs2x-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sfs2x_py-0.1.1.tar.gz -
Subject digest:
9876566130803c69344804a5c2e63a6c215a9bccac11c7196e0969b40fe3d30d - Sigstore transparency entry: 1097320120
- Sigstore integration time:
-
Permalink:
KeepALifeUS/sfs2x-py@2037f6acde3be7bc68750e76b74d2cd066454b34 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/KeepALifeUS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2037f6acde3be7bc68750e76b74d2cd066454b34 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sfs2x_py-0.1.1-py3-none-any.whl.
File metadata
- Download URL: sfs2x_py-0.1.1-py3-none-any.whl
- Upload date:
- Size: 13.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee0856eabd0f9444b71db40f731fbf64a6483c104800b2ac1765f7a3e6bf1b4a
|
|
| MD5 |
c17a50824fda9c641ecb7c327e8961df
|
|
| BLAKE2b-256 |
24e37a211ffb0678a5d3169a191b08418eac4d521fa81f89c19c748dea6f5b73
|
Provenance
The following attestation bundles were made for sfs2x_py-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on KeepALifeUS/sfs2x-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sfs2x_py-0.1.1-py3-none-any.whl -
Subject digest:
ee0856eabd0f9444b71db40f731fbf64a6483c104800b2ac1765f7a3e6bf1b4a - Sigstore transparency entry: 1097320188
- Sigstore integration time:
-
Permalink:
KeepALifeUS/sfs2x-py@2037f6acde3be7bc68750e76b74d2cd066454b34 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/KeepALifeUS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2037f6acde3be7bc68750e76b74d2cd066454b34 -
Trigger Event:
push
-
Statement type: