Skip to content

kyll3r/GunBound-Java-Server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GunBound Java Emulator - Thor's Hammer (Server Emulator)

This is a server emulator for the classic multiplayer online game GunBound, specifically targeting the Thor's Hammer version (GIS v376 / GBS v404) with Ex-Item and Power User support. Built with Java, it leverages the high-performance Netty networking framework to handle asynchronous, event-driven socket communication with game clients.


πŸ—οΈ System Architecture and Network Flow

The emulator is split into three independent server daemons cooperating to manage player sessions:

graph TD
    Client[GunBound Client] -->|TCP 8372| Broker[Broker Server]
    Client -->|TCP 8360| GameServer[Game Server]
    Client -->|TCP 8352| BuddyServer[Buddy Server]
    
    Broker -.->|Returns channel list| Client
    GameServer -->|Persists data| DB[(MariaDB / MySQL)]
    BuddyServer -->|Friends & Messages| DB
Loading
  1. Broker Server (GunBoundBrokerServer - Default Port: 8372):
    • The initial connection point for the client.
    • Handles commands 0x1013 (Broker Authentication Request) and 0x1100 (Server Directory Request).
    • Returns a dynamic list of active Game Servers (0x1102), detailing names, descriptions, IP addresses, ports, and real-time utilization.
  2. Game Server (GunBoundGameServer - Default Port: 8360):
    • The primary game daemon managing channels, lobbies, and game rooms.
    • Handles user authentication, channel chat, lobby synchronization, room lifecycle, map selection, tank (mobile) pick validation, Avatar Shop transactions, and live gameplay matches.
  3. Buddy Server (GunBoundBuddyServer - Default Port: TCP 8352):
    • Responsible for managing friend lists, instant messaging, active status tracking (online/offline), and the game's internal mail system (Buddy Mail).

🧠 Design Patterns and Technical Decisions

The emulator is designed to be highly scalable, thread-safe, and modular. The key architectural and design patterns used include:

1. Reactive & Non-Blocking Networking (Netty Pipeline)

  • Event-Driven Architecture: Network I/O is processed asynchronously using Netty's ChannelPipeline.
  • Packet Framing (Decoding): Implemented in PacketDecoder, which intercepts the TCP stream and buffers incoming data until the full payload size (specified in the first 2 bytes as a little-endian short) is received before dispatching it to downstream handlers.
  • Idle State Detection: An IdleStateHandler in the pipeline monitors channel inactivity (e.g., missing keep-alive packets) and gracefully closes inactive sockets, preventing resource leaks and zombie sessions.

2. Modern Concurrency Model

  • Java 21 Virtual Threads: GunBoundStarter initiates the server instances using Executors.newVirtualThreadPerTaskExecutor(). This allows servers to run on lightweight virtual threads, drastically reducing operating system thread overhead.
  • Serialized Room Action Queue: To prevent race conditions on shared game room states (such as concurrent HP updates, ready/unready state changes, or player actions) without blocking the main event loops or incurring heavy synchronization locks, each GameRoom operates an Actor-like Message Queue:
    • Actions are encapsulated into Runnable tasks.
    • Tasks are submitted to the room's task queue via submitAction(Runnable, ChannelHandlerContext).
    • A thread-safe loop managed by an AtomicBoolean (processing) ensures that only one task from the queue is executed at a time, running on the client's respective Netty EventLoop thread.
  • Thread-Safe Data Structures: Utilizes ConcurrentHashMap for maps containing player sessions and game states, and PriorityBlockingQueue to track and reuse vacant room slots (ensuring new players are always assigned the lowest available slot ID between 0 and 7).

3. Separation of Concerns in Packet Processing

  • Opcode Dispatcher Registry (Factory Pattern): OpcodeReaderFactory maps numeric command opcodes to functional execution blocks (BiConsumer<ChannelHandlerContext, byte[]>). This decoupled routing registry replaces massive conditional blocks (if/else ladders) and facilitates clean protocol extension.
  • Decoupled Readers & Writers:
    • Readers: Classes under packets.readers extract and parse raw binary structures (ByteBuf), validate arguments, and delegate business actions to services or room controllers.
    • Writers: Classes under packets.writers are purely responsible for serializing Java objects and game states back into the protocol-compliant byte structures expected by the GunBound client.

4. Persistence and Data Access Architecture (DAO & Services)

  • HikariCP Connection Pooling: Configured with production-grade parameters in DatabaseManager (2-minute keep-alive ping, ConnectionTestQuery set to SELECT 1, and a 30-minute maximum connection lifetime) to eliminate driver-level timeouts and "connection is closed" errors.
  • DAO Pattern (Data Access Object):
    • Persistent operations are declared in interface classes (e.g., UserDAO, ChestDAO, StatsDAO).
    • Raw SQL query generation and transactional updates are isolated inside JDBC implementation classes (e.g., UserJDBC, ChestJDBC).
    • Instantation and dependency injection are managed through the centralized DAOFactory.
  • Service Layer Pattern: Classes (such as UserServiceImpl and ShopServiceImpl) decouple controllers and readers from direct database drivers, encapsulating the game rules (e.g., validating purchase conditions, calculating gold and GP updates).

πŸ” GunBound Protocol Cryptography

A key component of the emulator is the handling of GunBound's custom binary security layers:

Static Encryption

Used during the initial handshake, broker communication, and login phases. It uses AES-128 in ECB mode (AES/ECB/NoPadding) with a hardcoded static key: FF B3 B3 BE AE 97 AD 83 B9 61 0E 23 A4 3C 2E B0

Dynamic Encryption

Once a user is authenticated, the client and server transition to dynamic cryptography:

  1. Key Derivation: The server derives a unique 128-bit key per session by concatenating the player's username, password, and a randomized 16-byte authToken generated during authentication.
  2. Custom SHA-0 Variant: This concatenated string is hashed using a custom implementation of the SHA-0 hashing algorithm.
  3. Truncation and Endian Swap: The resulting 20-byte hash is truncated to 16 bytes. These bytes are then swapped in 4-byte blocks (little-endian word rotation) to form the final AES-128 key.
  4. Command Checksums:
    • Outgoing dynamic payloads must align to 12-byte boundaries.
    • For every 12-byte payload chunk, the server prepends a 4-byte command checksum calculated as 0x8631607E + COMMAND_OPCODE.
    • The final 16-byte blocks are then encrypted with the derived dynamic AES key. Upon receipt, the server decrypts the payload, validates the command checksum, and discards it to extract the original 12-byte segment.

Sequence Validation (LCG)

To prevent packet replay attacks, the GunBound protocol uses a sequence checksum inside the 6-byte header, calculated dynamically based on the total bytes sent (sumPacketLength) using a Linear Congruential Generator (LCG): $$\text{Sequence} = (((\text{sumPacketLength} \times \text{0x43FD}) \ &amp; \ \text{0xFFFF}) - \text{0x53FD}) \ &amp; \ \text{0xFFFF}$$ The initial handshake packet uses a fixed seed value of 0xCBEB.


πŸ“ Project Directory Structure

src/main/java/br/com/gunbound/emulator
β”‚
β”œβ”€β”€ GunBoundStarter.java          # Main server bootstrapper (spawns Broker, Game, and Buddy servers)
β”œβ”€β”€ ServerConfig.java             # Singleton configuration loader for config.properties
β”œβ”€β”€ ConnectionManager.java        # Core registry managing active Netty channels
β”‚
β”œβ”€β”€ broker/                       # Directory/Router Server (Broker)
β”‚   β”œβ”€β”€ GunBoundBrokerServer.java
β”‚   └── GunBoundBrokerServerHandler.java
β”‚
β”œβ”€β”€ buddy/                        # Social & Friend List Server (Buddy)
β”‚   β”œβ”€β”€ GunBoundBuddyServer.java
β”‚   β”œβ”€β”€ GunBundBuddyServerHandler.java
β”‚   β”œβ”€β”€ config/                   # Buddy decoders and logging handlers
β”‚   β”œβ”€β”€ db/
β”‚   β”œβ”€β”€ entities/
β”‚   └── packet/                   # Buddy packet readers and writers
β”‚
β”œβ”€β”€ db/                           # Database Manager & HikariCP Pool Configuration
β”‚   β”œβ”€β”€ DatabaseManager.java      # Configures HikariCP datasources
β”‚   └── DB.java
β”‚
β”œβ”€β”€ gameserver/                   # Core Game Logic Server
β”‚   β”œβ”€β”€ GunBoundGameServer.java
β”‚   β”œβ”€β”€ handlers/                 # Netty pipeline handlers for game server sockets
β”‚   β”œβ”€β”€ lobby/                    # Channel, Lobby and chat coordination
β”‚   β”œβ”€β”€ playdata/                 # Game assets metadata (maps, spawn points)
β”‚   β”œβ”€β”€ packets/                  # Protocol routing, opcodes, and factory definitions
β”‚   β”‚   β”œβ”€β”€ OpcodeReaderFactory.java # Opcode command router registry
β”‚   β”‚   β”œβ”€β”€ readers/              # Message payload decoders (Login, Chat, Shop, Room settings)
β”‚   β”‚   └── writers/              # Binary response packet builders
β”‚   └── room/                     # Match room logic
β”‚       β”œβ”€β”€ GameRoom.java         # Room state controller & room-bound action queue
β”‚       β”œβ”€β”€ RoomManager.java      # Singleton managing room allocations
β”‚       └── onlymob/              # Restrictive mode implementations (e.g. Only Mob Commands)
β”‚
β”œβ”€β”€ model/                        # Data Entities & Persistence Layer (DAOs)
β”‚   β”œβ”€β”€ entities/                 # Data transfer objects (User, Avatar, Chest, ServerOption)
β”‚   └── DAO/                      # Data Access interfaces & JDBC implementations (impl)
β”‚
β”œβ”€β”€ services/                     # Business Logic Services (Shop, Users, Auth)
β”‚   └── impl/                     # Service implementation layers
β”‚
└── utils/                        # Utilities & Cryptographic helpers
    β”œβ”€β”€ crypto/
    β”‚   └── GunBoundCipher.java   # Static/Dynamic cipher algorithms & SHA-0 implementation
    β”œβ”€β”€ PacketDecoder.java        # Netty ByteToMessageDecoder for packet sizes
    └── PacketUtils.java          # LCG Sequence generators, packet header assemblers

πŸ› οΈ Prerequisites

To build and run this emulator, ensure your development environment has:

  • Java Development Kit (JDK) 21 or higher (Required for Virtual Thread features).
  • Apache Maven 3.8 or higher.
  • MariaDB 10.4+ (or MySQL 8.0+).
  • GunBound client files (Thor's Hammer edition, GIS v376 or GBS v404).

βš™οΈ Environment Setup

1. Database Setup

  1. Create a new database schema in your database server (e.g., gbth).
  2. Import the required SQL schema tables (user, game, chest, menu, etc.).

2. Configuration Properties

Create a folder named config/ in your project's root directory, and create a file named config.properties inside it.

Configure the following mandatory keys:

# ===============================================
# GENERAL SERVER CONFIGURATIONS
# ===============================================
# Public IP of the server where the emulator will run.
# Use 127.0.0.1 for local testing.
server.public.ip=127.0.0.1

# ===============================================
# BROKER SERVER CONFIGURATIONS
# ===============================================
# Port that the Broker Server will use to accept initial connections.
broker.port=8372
broker.serv1.name=GunBound Legacy
broker.serv1.descr=Avatar OFF

# ===============================================
# GAME SERVER CONFIGURATIONS
# ===============================================
# Port that the main Game Server will use.
gameserver.port=8360

# Probability of getting Dragon/Knight (hidden tanks)
gameserver.tank.hidden.ratio=10
gameserver.goldfactor=100
gameserver.scorefactor=100
gameserver.stage0_probability=5

# Event settings
gameserver.eventtrigger=1
gameserver.eventactprop=50
# Honk (megaphone) price
gameserver.honkprice=10000
# Balloon (chat bubble) price
gameserver.balloonprice=50000
# Talk text color price
gameserver.colorprice=50000

# PowerUser settings
gameserver.superuseritem=204801

gameserver.channelment=#GunBound Legacy Thor's Hammer
gameserver.channeldaymsg=*Bom Dia
gameserver.channelafternoonmsg=*Boa Tarde
gameserver.channelnightmsg=*Boa Noite
gameserver.roomment=&Jogue Limpo!

gameserver.versionfirst=100
gameserver.versionlast=900
gameserver.passableauthority=0

gameserver.funcrestrict=1040384

# ===============================================
# BUDDY SERVER CONFIGURATIONS
# ===============================================
# TCP Port that the Buddy Server (friends system) will use.
buddy.port=8352
# UDP Port for the Buddy Server chat/presence service.
buddy.udp.port=8381

# Database Credentials
db.url=jdbc:mariadb://localhost:3306/gbth
db.user=your_db_username
db.password=your_db_password
db.useSSL=false

πŸš€ Running the Emulator

  1. Open your terminal in the root directory of the repository.
  2. Compile the application and download dependencies using Maven:
    mvn clean install
  3. Run the compiled application via the bootsrapper class:
    mvn exec:java -Dexec.mainClass="br.com.gunbound.emulator.GunBoundStarter"
  4. If configured correctly, startup logs will output the HikariCP connection pool initializing, followed by confirmation messages for the Broker, Game, and Buddy servers listening on their respective ports.

🀝 Contributing

Contributions are welcome! To contribute:

  1. Fork this repository.
  2. Create your feature branch:
    git checkout -b feature/MyNewFeature
  3. Commit your changes with clear descriptions:
    git commit -m 'feat: add guild chat support'
  4. Push to your branch:
    git push origin feature/MyNewFeature
  5. Submit a Pull Request.

πŸŽ–οΈ Credits, Support and Tributes

Credits: KyLL3R

Special Thanks: ChoVinisTa, Tiddus, Jglim, Rizzo

External Plugins

Modern Client

πŸ•―οΈ Special Tribute (In Memoriam)

  • JoBaS (Joabe Rodrigues)

Screenshots

Game Room Game Play Avatar Shop

GunBound was more than just a game for many of us it was a part of our childhood and a community that created unforgettable memories.

I hope that one day Softnyx will entrust the future of GunBound to the right people, allowing its golden days to shine once again.

πŸ“œ License and Disclaimers

This project is licensed under the MIT License. See LICENSE.txt for license text.

Warning

Legal Disclaimer: The GunBound game client and all associated artwork, assets, and trademarks are the exclusive property of Softnyx. This server emulator is a non-commercial, community-driven project created strictly for educational, research, and software preservation purposes.

About

A complete GunBound Thor's Hammer server emulator featuring BrokerServer, BuddyServer, and GameServer, built to preserve and keep alive the classic GunBound experience.

Topics

Resources

License

Stars

3 stars

Watchers

1 watching

Forks

Releases

No releases published

Contributors

Languages