261 lines
6.8 KiB
Markdown
261 lines
6.8 KiB
Markdown

|
|
|
|
# Trade
|
|
|
|
`Trade` is a NeoForge mod for Minecraft `1.21.1` that adds a secure player-to-player trading interface inspired by Runescape.
|
|
|
|
Players can request a trade, review both offers in a shared GUI, accept once to lock the offer, and confirm a second time to complete the exchange.
|
|
|
|
## Features
|
|
|
|
- Player-to-player trade requests with an accept / decline handshake
|
|
- Shared trade screen with separate offer areas for both players
|
|
- Two-step confirmation flow
|
|
- Quantity-based item selection with quick amounts and `Trade X`
|
|
- Warning if items are removed/modified
|
|
- Inventory-safe finalization: nothing changes until safety and security checks pass and the trade succeeds
|
|
- Configurable trade safety checks to prevent dangerous mid-combat or mid-movement trading
|
|
- Configurable per-player request cooldowns
|
|
- Per-player trade toggles and ignore list support
|
|
- Admin-controlled player and item trade blacklists, with config defaults and live commands
|
|
- File-based trade audit log for server operators
|
|
|
|
## Player Usage
|
|
|
|
### Starting a trade
|
|
|
|
Primary flow:
|
|
|
|
- Use the trade keybind (default: `G`) while looking at another player
|
|
|
|
Command option:
|
|
|
|
```mcfunction
|
|
/trade <player>
|
|
```
|
|
|
|
When a request is sent, the target player receives chat text with a clickable accept link.
|
|
|
|
They can also respond manually:
|
|
|
|
```mcfunction
|
|
/trade yes
|
|
/trade no
|
|
```
|
|
|
|
### In the trade screen
|
|
|
|
- Click an item in your inventory to trade `1`
|
|
- Right-click an item to open the quantity menu
|
|
- Use `Trade X` to enter a custom amount
|
|
- Click `Accept` when your offer is ready
|
|
- Once both players accept, the screen enters the confirmation stage
|
|
- Click `Confirm` to finalize
|
|
|
|
If a player reduces or removes items from an offer:
|
|
|
|
- any pending accepts / confirms are invalidated
|
|
- the changed offer slot gets a blinking red border and `!`
|
|
- the trade window shows a red `Trade Modified` warning
|
|
|
|
## Commands
|
|
|
|
### Player commands
|
|
|
|
```mcfunction
|
|
/trade <player>
|
|
/trade yes
|
|
/trade no
|
|
/trade toggle
|
|
/trade on
|
|
/trade off
|
|
/trade ignore <player>
|
|
/trade unignore <player>
|
|
/trade ignorelist
|
|
```
|
|
|
|
### Admin commands
|
|
|
|
Server operators can manage persistent live blacklists with:
|
|
|
|
```mcfunction
|
|
/trade admin playerblock add <player|uuid>
|
|
/trade admin playerblock remove <player|uuid>
|
|
/trade admin playerblock list
|
|
/trade admin itemblock add item <namespace:item>
|
|
/trade admin itemblock remove item <namespace:item>
|
|
/trade admin itemblock add tag <namespace:tag>
|
|
/trade admin itemblock remove tag <namespace:tag>
|
|
/trade admin itemblock add mod <modid>
|
|
/trade admin itemblock remove mod <modid>
|
|
/trade admin itemblock list
|
|
```
|
|
|
|
### Command behavior
|
|
|
|
- `/trade <player>` sends a trade request
|
|
- `/trade yes` accepts the current pending trade request
|
|
- `/trade no` declines the current pending trade request
|
|
- `/trade toggle` flips whether you accept incoming trade requests
|
|
- `/trade on` enables incoming trade requests
|
|
- `/trade off` disables incoming trade requests
|
|
- `/trade ignore <player>` blocks trade requests from that online player
|
|
- `/trade unignore <player>` removes that online player from your ignore list
|
|
- `/trade ignorelist` shows your ignored players
|
|
|
|
## Trade Safety
|
|
|
|
By default, the mod blocks trade requests or acceptance unless both players are in a safe state.
|
|
|
|
Default safeguards:
|
|
|
|
- on solid ground
|
|
- standing still
|
|
- not recently damaged
|
|
- not on fire
|
|
- not in liquid
|
|
- not sleeping
|
|
- not gliding
|
|
- not mounted
|
|
- in the same dimension
|
|
|
|
There is also a special delayed-accept flow for the most common transient failure:
|
|
|
|
- if the other player accepts while you are only moving or in the air, the request does not fail immediately
|
|
- instead, you get an on-screen countdown
|
|
- if you get safe in time and remain still long enough, the trade opens automatically
|
|
|
|
## Final Validation
|
|
|
|
When both players confirm, the trade is checked one last time before any real inventory is changed.
|
|
|
|
The trade verifies:
|
|
|
|
- both players are still in the same dimension, if that config is enabled
|
|
- both players are still within configured trade distance, if enabled
|
|
- both live inventories still match the snapshots taken when the trade started
|
|
- both players can receive the incoming items
|
|
- both players have re-accepted after any offer changes
|
|
|
|
If any check fails, the trade is cancelled and both players receive an explicit chat message explaining why.
|
|
|
|
## Configuration
|
|
|
|
Server config values live under the `trade` section.
|
|
|
|
### Request / range
|
|
|
|
- `tradeCommandProximity`
|
|
- default: `0`
|
|
- `0` disables range checks
|
|
- `1+` requires players to be within that many blocks to request, accept, and finalize a trade
|
|
|
|
- `requestTimeoutSeconds`
|
|
- default: `30`
|
|
- number of seconds before a pending trade request expires
|
|
|
|
- `requestCooldownSeconds`
|
|
- default: `5`
|
|
- number of seconds a player must wait before sending another trade request
|
|
|
|
### Debug
|
|
|
|
- `enableDebugFeatures`
|
|
- default: `false`
|
|
- enables debug commands and debug UI/testing tools
|
|
|
|
### Trade flow
|
|
|
|
- `requireSecondConfirmation`
|
|
- default: `true`
|
|
- requires the second confirm step after both players accept the offer
|
|
|
|
- `showTradeModifiedWarnings`
|
|
- default: `true`
|
|
- shows the `Trade Modified` warning and changed-slot highlights when offers are reduced or removed
|
|
|
|
### Safety
|
|
|
|
- `requireOnGround`
|
|
- default: `true`
|
|
|
|
- `requireStationary`
|
|
- default: `true`
|
|
|
|
- `stationarySpeedThreshold`
|
|
- default: `0.03`
|
|
|
|
- `requireNoRecentDamage`
|
|
- default: `true`
|
|
|
|
- `noDamageSeconds`
|
|
- default: `10`
|
|
|
|
- `requireNotOnFire`
|
|
- default: `true`
|
|
|
|
- `requireNotInLiquid`
|
|
- default: `true`
|
|
|
|
- `requireNotSleeping`
|
|
- default: `true`
|
|
|
|
- `requireNotFallFlying`
|
|
- default: `true`
|
|
|
|
- `requireNotRiding`
|
|
- default: `true`
|
|
|
|
- `requireSameDimension`
|
|
- default: `true`
|
|
|
|
### Admin blacklists
|
|
|
|
- `adminDisabledPlayerUuids`
|
|
- default: `[]`
|
|
- UUIDs of players who cannot use the trade system at all
|
|
|
|
- `adminBlacklistedItemIds`
|
|
- default: command blocks, command block minecarts, barriers, bedrock, end portal blocks/frames, structure blocks, jigsaws, lights, and spawners
|
|
- exact item ids that cannot be traded, like `minecraft:diamond`
|
|
|
|
- `adminBlacklistedItemTags`
|
|
- default: `[]`
|
|
- item tags that cannot be traded, like `minecraft:logs`
|
|
|
|
- `adminBlacklistedMods`
|
|
- default: `[]`
|
|
- mod namespaces that cannot be traded, like `minecraft`
|
|
|
|
Config blacklist entries are treated as defaults. Live admin commands add and remove separate saved entries that persist across restarts.
|
|
|
|
## Audit Log
|
|
|
|
The mod writes a trade audit log to:
|
|
|
|
```text
|
|
logs/trade.log
|
|
```
|
|
|
|
Entries include:
|
|
|
|
- trade requests
|
|
- request accepts / declines / expirations
|
|
- trade opens
|
|
- trade cancels
|
|
- trade completions
|
|
- player names
|
|
- UUIDs
|
|
- dimensions
|
|
- block coordinates
|
|
- items offered by each side
|
|
- final result text
|
|
|
|
## Debug Mode
|
|
|
|
Debug tools are disabled by default and only available when:
|
|
|
|
- `enableDebugFeatures = true`
|
|
|
|
When enabled, the mod exposes `/trade debug ...` commands and on-screen debug controls for single-client testing.
|