diff --git a/docs/zh/API documentation/Client-Side.md b/docs/zh/API documentation/Client-Side.md
new file mode 100644
index 00000000..b1106a18
--- /dev/null
+++ b/docs/zh/API documentation/Client-Side.md
@@ -0,0 +1,1502 @@
+## 目录
+
+### MPVehicleGE
+
+- [Vehicle Functions(车辆函数)](#vehicle-functions)
+- [Player Functions(玩家函数)](#player-functions)
+- [Nametag Functions(昵称标签函数)](#nametag-functions)
+- [Role Functions(角色函数)](#role-functions)
+- [Navigation Functions(导航函数)](#navigation-functions)
+- [Object Methods(对象方法)](#object-methods)
+- [Event Hooks(事件钩子)](#event-hooks)
+
+### MPConfig
+
+- [MPConfig Functions(MPConfig函数)](#mpconfig-functions)
+
+### MPCoreNetwork
+
+- [MPCoreNetwork Functions](#mpcorenetwork-functions)
+
+### MPGameNetwork
+
+- [事件系统功能](#event-system-functions)
+- [按键功能](#keypress-functions)
+- [用户界面功能](#ui-functions)
+- [MPGameNetwork 回调](#mpgamenetwork-callbacks)
+
+### MPHelpers
+
+- [编码函数](#encoding-functions)
+- [颜色函数](#color-functions)
+- [字符串函数](#string-functions)
+- [表函数](#table-functions)
+- [调试函数](#debug-functions)
+
+---
+
+## 车辆函数
+
+### `getGameVehicleID(serverVehicleID)`
+
+将 serverVehicleID 解析为 gameVehicleID
+
+**参数:**
+
+- `serverVehicleID` (字符串)- 格式:“X-Y”,其中 X 为玩家 ID,Y 为车辆 ID
+
+**返回:**
+
+- (数字)- 游戏内部车辆 ID
+- (编号) `-1` - 如果车辆未知
+
+**用法:**
+
+```lua
+local gameID = extensions.MPVehicleGE.getGameVehicleID("0-0")
+```
+
+---
+
+### `getServerVehicleID(gameVehicleID)`
+
+将 gameVehicleID 解析为 serverVehicleID
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**返回:**
+
+- (字符串)- 服务器车辆 ID(例如,“0-0”)
+- (nil)- 如果 gameVehicleID 未知
+
+**用法:**
+
+```lua
+local serverID = extensions.MPVehicleGE.getServerVehicleID(11171)
+```
+
+---
+
+### `getVehicleByServerID(serverVehicleID)`
+
+返回此车辆的完整车辆表
+
+**参数:**
+
+- `serverVehicleID` (字符串)- 格式:“X-Y”
+
+**返回:**
+
+- (表)- 车辆信息(名称、游戏车辆 ID、jbeam、所有者 ID、所有者名称、是否本地、是否已生成等)
+- (nil)- 如果服务器车辆 ID 无效
+
+**用法:**
+
+```lua
+local vehicle = extensions.MPVehicleGE.getVehicleByServerID("0-0")
+if vehicle then
+ print("Owner: " .. vehicle.ownerName)
+end
+```
+
+---
+
+### `getVehicleByGameID(gameVehicleID)`
+
+返回此车辆的完整车辆表
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**返回:**
+
+- (表)- 车辆信息
+- (nil) - 如果 gameVehicleID 无效
+
+**用法:**
+
+```lua
+local vehicle = extensions.MPVehicleGE.getVehicleByGameID(11171)
+```
+
+---
+
+### `isOwn(gameVehicleID)`
+
+检查给定车辆是否属于此客户端
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**返回:**
+
+- (boolean)- 如果车辆属于此客户端,则返回 true
+
+**用法:**
+
+```lua
+if extensions.MPVehicleGE.isOwn(11171) then
+ print("This is my vehicle")
+end
+```
+
+---
+
+### `getOwnMap()`
+
+返回一个包含此客户端拥有的所有车辆的表。
+
+**参数:**
+
+- 无
+
+**返回:**
+
+- (表)- 已拥有车辆地图`{[gameVehicleID] = vehicles_subtable}`
+
+**用法:**
+
+```lua
+local myVehicles = extensions.MPVehicleGE.getOwnMap()
+```
+
+---
+
+### `getVehicleMap()`
+
+返回一个包含所有已知多人游戏载具的表。
+
+**参数:**
+
+- 无
+
+**返回:**
+
+- (表)- 所有车辆的地图`{[serverVehicleID] = gameVehicleID}`
+
+**用法:**
+
+```lua
+local allVehicles = extensions.MPVehicleGE.getVehicleMap()
+```
+
+---
+
+### `getDistanceMap()`
+
+返回每个多人游戏载具到此客户端视角的距离
+
+**参数:**
+
+- 无
+
+**返回:**
+
+- (表)- 距离地图`{[gameVehicleID] = distanceInMeters}`
+
+**用法:**
+
+```lua
+local distances = extensions.MPVehicleGE.getDistanceMap()
+```
+
+---
+
+### `getNicknameMap()`
+
+返回所有多人游戏车辆 ID 及其所有者名称
+
+**参数:**
+
+- 无
+
+**返回:**
+
+- (表)- 昵称映射表`{[gameVehicleID] = ownerName}`
+
+**用法:**
+
+```lua
+local nicknameMap = extensions.MPVehicleGE.getNicknameMap()
+```
+
+---
+
+### `getVehicles()`
+
+返回完整的车辆表
+
+**参数:**
+
+- 无
+
+**返回:**
+
+- (表)- 所有车辆`{[serverVehicleID] = vehicles_subtable}`
+
+**用法:**
+
+```lua
+local vehicles = extensions.MPVehicleGE.getVehicles()
+for serverID, vehicle in pairs(vehicles) do
+ print("Vehicle: " .. vehicle.jbeam)
+end
+```
+
+---
+
+## 玩家函数
+
+### `getPlayerByName(name)`
+
+返回该玩家的信息表和 ID
+
+**参数:**
+
+- `name` (字符串)- 玩家名称
+
+**返回:**
+
+- (表)- 玩家信息(姓名、玩家ID、角色、载具等)
+- (数字)- 玩家 ID
+- (nil)- 如果未找到玩家
+
+**用法:**
+
+```lua
+local player, playerID = extensions.MPVehicleGE.getPlayerByName("John")
+if player then
+ print("Player ID: " .. playerID)
+end
+```
+
+---
+
+### `getPlayers()`
+
+返回完整的玩家表
+
+**参数:**
+
+- 无
+
+**返回:**
+
+- (表)- 所有玩家`{[playerID] = players_subtable}`
+
+**用法:**
+
+```lua
+local players = extensions.MPVehicleGE.getPlayers()
+for playerID, player in pairs(players) do
+ print("Player: " .. player.name)
+end
+```
+
+---
+
+## 昵称标签函数
+
+### `setPlayerNickPrefix(targetName, tagSource, text)`
+
+给玩家的名字标签添加前缀(显示在名字前面)
+
+**参数:**
+
+- `targetName` (字符串)- 玩家名称
+- `tagSource` (字符串)- 此前缀的唯一标识符
+- `text` (字符串)- 显示在名称之前的文本
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.setPlayerNickPrefix("John", "RANK", "1st.")
+-- Result: "1st. John"
+```
+
+---
+
+### `setPlayerNickSuffix(targetName, tagSource, text)`
+
+给玩家的名字标签添加后缀(显示在名字后面)
+
+**参数:**
+
+- `targetName` (字符串)- 玩家名称
+- `tagSource` (字符串)- 此后缀的唯一标识符
+- `text` (字符串)- 名称后显示的文本
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.setPlayerNickSuffix("John", "STATUS", "[AFK]")
+-- Result: "John [AFK]"
+```
+
+---
+
+### `hideNicknames(hide)`
+
+开启或关闭 BeamMP 的姓名标签绘制功能
+
+**参数:**
+
+- `hide` (boolean) - True 表示隐藏姓名标签,False 表示显示姓名标签
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.hideNicknames(true) -- Hide
+extensions.MPVehicleGE.hideNicknames(false) -- Show
+```
+
+---
+
+### `toggleNicknames()`
+
+切换显示姓名标签
+
+**参数:**
+
+- 无
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.toggleNicknames()
+```
+
+---
+
+## 角色函数
+
+### `setPlayerRole(playerID, tag, shorttag, red, green, blue)`
+
+为玩家设置自定义角色
+
+**参数:**
+
+- `playerID` (数字)- 玩家的ID
+- `tag` (字符串)- 角色标签(例如,“VIP”)
+- `shorttag` (字符串)- 简短版本(例如,“V”)
+- `red` (数字)- 红色通道(0-255)
+- `green` (数字)- 绿色通道(0-255)
+- `blue` (数字)- 蓝色通道(0-255)
+
+**返回:**
+
+- (布尔值,字符串)- 如果玩家不存在`false, "player not found"`
+- (布尔值,字符串)- 如果参数无效,则`false, error`
+- (无)——关于成功无信息
+
+**用法:**
+
+```lua
+local success, error = extensions.MPVehicleGE.setPlayerRole(0, "VIP", "V", 255, 215, 0)
+if success == false then
+ print("Error: " .. error)
+end
+```
+
+---
+
+### `clearPlayerRole(playerID)`
+
+清除玩家的自定义角色
+
+**参数:**
+
+- `playerID` (数字)- 玩家的ID
+
+**返回:**
+
+- (布尔值)- 始终返回`false` (实现怪癖 - 用于检查玩家是否存在)
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.clearPlayerRole(0)
+```
+
+---
+
+### `setVehicleRole(playerIDVehicleID, tag, shorttag, red, green, blue)`
+
+为特定车辆设置自定义角色
+
+**参数:**
+
+- `playerIDVehicleID` (字符串)- 车辆 ID(格式:“0-0”)
+- `tag` (字符串)- 角色标签
+- `shorttag` (字符串)- 短版本
+- `red` (数字)- 红色(0-255)
+- `green` (数字)- 绿色(0-255)
+- `blue` (数字)- 蓝色(0-255)
+
+**返回:**
+
+- (布尔值,字符串)- 如果车辆不存在`false, "vehicle not found"`
+- (布尔值,字符串)- 如果参数无效,则`false, error`
+- (无)——关于成功无信息
+
+**用法:**
+
+```lua
+local success, error = extensions.MPVehicleGE.setVehicleRole("0-0", "Police", "POL", 0, 0, 255)
+if success == false then
+ print("Error: " .. error)
+end
+```
+
+---
+
+### `clearVehicleRole(playerIDVehicleID)`
+
+清除车辆的自定义角色
+
+**参数:**
+
+- `playerIDVehicleID` (字符串)- 车辆 ID(格式:“0-0”)
+
+**返回:**
+
+- (布尔值)- 始终返回`false` (实现特性 - 用于检查车辆是否存在)
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.clearVehicleRole("0-0")
+```
+
+---
+
+## 导航函数
+
+### `groundmarkerToPlayer(targetName)`
+
+设置一条通往目标玩家位置的地面标记路线(静态)
+
+**参数:**
+
+- `targetName` (字符串)- 玩家名称,如果为 nil 则清除
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.groundmarkerToPlayer("John") -- Set
+extensions.MPVehicleGE.groundmarkerToPlayer(nil) -- Clear
+```
+
+---
+
+### `groundmarkerFollowPlayer(targetName, dontfollow)`
+
+设置跟随目标玩家的地面标记路线
+
+**参数:**
+
+- `targetName` (字符串)- 玩家名称,如果为 nil 则停止
+- `dontfollow` (布尔值)- 如果为true,则创建静态标记
+
+**用法:**
+
+```lua
+extensions.MPVehicleGE.groundmarkerFollowPlayer("John") -- Follow
+extensions.MPVehicleGE.groundmarkerFollowPlayer("John", true) -- Static
+extensions.MPVehicleGE.groundmarkerFollowPlayer(nil) -- Stop
+```
+
+---
+
+### `queryRoadNodeToPosition(targetPosition, owner)`
+
+查找距离目标位置最近的道路节点
+
+**参数:**
+
+- `targetPosition` (vec3 或表)- 目标位置,包含 x、y、z 坐标
+- `owner` (字符串)- 可选标识符(默认值:“target”)
+
+**返回:**
+
+- (布尔值)- 成功状态
+- (数字)- 节点 ID(如果成功)
+
+**用法:**
+
+```lua
+local pos = vec3(100, 200, 50)
+local success, nodeID = extensions.MPVehicleGE.queryRoadNodeToPosition(pos)
+```
+
+---
+
+## 对象方法
+
+### 玩家对象方法
+
+#### `player:setNickPrefix(tagSource, text)`
+
+设置该玩家名称标签的前缀
+
+**参数:**
+
+- `tagSource` (字符串)- 唯一标识符
+- `text` (字符串)- 要显示的文本(或 nil 表示不显示)
+
+**用法:**
+
+```lua
+local player = extensions.MPVehicleGE.getPlayerByName("John")
+if player then
+ player:setNickPrefix("STATUS", "[AFK]")
+end
+```
+
+---
+
+#### `player:setNickSuffix(tagSource, text)`
+
+为该玩家的姓名标签设置后缀
+
+**参数:**
+
+- `tagSource` (字符串)- 唯一标识符
+- `text` (字符串)- 要显示的文本(或 nil 表示不显示)
+
+**用法:**
+
+```lua
+local player = extensions.MPVehicleGE.getPlayerByName("John")
+if player then
+ player:setNickSuffix("MISSION", "[In Mission]")
+end
+```
+
+---
+
+#### `player:setCustomRole(role)`
+
+为该玩家设置自定义角色
+
+**参数:**
+
+- `role` (表)- 角色表: `{backcolor = {r, g, b}, tag = string, shorttag = string}`
+
+**用法:**
+
+```lua
+local player = extensions.MPVehicleGE.getPlayerByName("John")
+if player then
+ player:setCustomRole({
+ backcolor = {r = 255, g = 0, b = 0},
+ tag = " [VIP]",
+ shorttag = " [V]"
+ })
+end
+```
+
+---
+
+#### `player:clearCustomRole()`
+
+清除该玩家的自定义角色
+
+**用法:**
+
+```lua
+local player = extensions.MPVehicleGE.getPlayerByName("John")
+if player then
+ player:clearCustomRole()
+end
+```
+
+---
+
+### 车辆对象方法
+
+#### `vehicle:getOwner()`
+
+返回此车辆的所有者
+
+**返回:**
+
+- (表)- 玩家对象
+- (数字)- 玩家 ID
+
+**用法:**
+
+```lua
+local vehicle = extensions.MPVehicleGE.getVehicleByServerID("0-0")
+if vehicle then
+ local owner, ownerID = vehicle:getOwner()
+ print("Owner: " .. owner.name)
+end
+```
+
+---
+
+#### `vehicle:setCustomRole(role)`
+
+为这辆车设置自定义角色
+
+**参数:**
+
+- `role` (表)- 角色表: `{backcolor = {r, g, b}, tag = string, shorttag = string}`
+
+**用法:**
+
+```lua
+local vehicle = extensions.MPVehicleGE.getVehicleByServerID("0-0")
+if vehicle then
+ vehicle:setCustomRole({
+ backcolor = {r = 0, g = 0, b = 255},
+ tag = " [Police]",
+ shorttag = " [POL]"
+ })
+end
+```
+
+---
+
+#### `vehicle:clearCustomRole()`
+
+清除此车辆的自定义角色
+
+**用法:**
+
+```lua
+local vehicle = extensions.MPVehicleGE.getVehicleByServerID("0-0")
+if vehicle then
+ vehicle:clearCustomRole()
+end
+```
+
+---
+
+#### `vehicle:setDisplayName(displayName)`
+
+为这辆车设置自定义显示名称
+
+**参数:**
+
+- `displayName` (字符串)- 要显示的自定义名称
+
+**用法:**
+
+```lua
+local vehicle = extensions.MPVehicleGE.getVehicleByServerID("0-0")
+if vehicle then
+ vehicle:setDisplayName("Patrol Car #1")
+end
+```
+
+---
+
+## 事件钩子
+
+BeamMP 提供事件钩子,您可以重写这些钩子以在特定事件发生时执行自定义代码。**请勿直接调用这些函数**,而应在保留原始功能的前提下对其进行重写。
+
+### 钩子模式
+
+重写函数时,务必保留原函数:
+
+```lua
+-- Save the original function
+local originalCallback = MPVehicleGE.onVehicleSpawned
+
+-- Override with your custom logic
+MPVehicleGE.onVehicleSpawned = function(gameVehicleID)
+ -- Call the original first
+ originalCallback(gameVehicleID)
+
+ -- Your custom code here
+ print("Vehicle spawned: " .. gameVehicleID)
+end
+```
+
+---
+
+### 可用的事件钩子
+
+#### `onUpdate(dt)`
+
+连接到多人游戏时,每一帧都会被调用
+
+**参数:**
+
+- `dt` (数值)- 自上一帧以来的时间间隔(秒)。
+
+**用法:**
+
+```lua
+local originalOnUpdate = MPVehicleGE.onUpdate
+MPVehicleGE.onUpdate = function(dt)
+ originalOnUpdate(dt)
+ -- Your frame-by-frame logic here
+end
+```
+
+---
+
+#### `onPreRender(dt)`
+
+在渲染每一帧之前调用
+
+**参数:**
+
+- `dt` (数值)- 时间差(秒)
+
+**注意:**此功能在内部处理名称标签渲染、距离计算和地面标记。
+
+**用法:**
+
+```lua
+local originalOnPreRender = MPVehicleGE.onPreRender
+MPVehicleGE.onPreRender = function(dt)
+ originalOnPreRender(dt)
+ -- Your pre-render logic here
+end
+```
+
+---
+
+#### `onVehicleSpawned(gameVehicleID)`
+
+当车辆生成时调用(包括本地和远程车辆)
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**用法:**
+
+```lua
+local originalOnVehicleSpawned = MPVehicleGE.onVehicleSpawned
+MPVehicleGE.onVehicleSpawned = function(gameVehicleID)
+ originalOnVehicleSpawned(gameVehicleID)
+
+ local vehicle = extensions.MPVehicleGE.getVehicleByGameID(gameVehicleID)
+ if vehicle then
+ print(vehicle.ownerName .. " spawned a " .. vehicle.jbeam)
+ end
+end
+```
+
+---
+
+#### `onVehicleDestroyed(gameVehicleID)`
+
+车辆被销毁/移除时调用
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**用法:**
+
+```lua
+local originalOnVehicleDestroyed = MPVehicleGE.onVehicleDestroyed
+MPVehicleGE.onVehicleDestroyed = function(gameVehicleID)
+ local vehicle = extensions.MPVehicleGE.getVehicleByGameID(gameVehicleID)
+ if vehicle then
+ print("Vehicle " .. vehicle.jbeam .. " was destroyed")
+ end
+
+ originalOnVehicleDestroyed(gameVehicleID)
+end
+```
+
+---
+
+#### `onVehicleSwitched(oldGameVehicleID, newGameVehicleID)`
+
+当玩家切换车辆时调用
+
+**参数:**
+
+- `oldGameVehicleID` (数字)- 先前的车辆 ID(或 -1)
+- `newGameVehicleID` (数字)- 新车辆 ID(或 -1)
+
+**用法:**
+
+```lua
+local originalOnVehicleSwitched = MPVehicleGE.onVehicleSwitched
+MPVehicleGE.onVehicleSwitched = function(oldID, newID)
+ originalOnVehicleSwitched(oldID, newID)
+
+ print("Switched from vehicle " .. oldID .. " to " .. newID)
+end
+```
+
+---
+
+#### `onVehicleResetted(gameVehicleID)`
+
+车辆重置时调用(仅限本地车辆)
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**用法:**
+
+```lua
+local originalOnVehicleResetted = MPVehicleGE.onVehicleResetted
+MPVehicleGE.onVehicleResetted = function(gameVehicleID)
+ originalOnVehicleResetted(gameVehicleID)
+
+ print("Vehicle " .. gameVehicleID .. " was reset")
+end
+```
+
+---
+
+#### `onVehicleColorChanged(gameVehicleID, index, paint)`
+
+当车辆的涂装颜色发生变化时调用
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+- `index` (数字)- 涂装槽索引(0、1 或 2)
+- `paint` (表) - 包含颜色信息的油漆数据
+
+**用法:**
+
+```lua
+local originalOnVehicleColorChanged = MPVehicleGE.onVehicleColorChanged
+MPVehicleGE.onVehicleColorChanged = function(gameVehicleID, index, paint)
+ originalOnVehicleColorChanged(gameVehicleID, index, paint)
+
+ print("Vehicle " .. gameVehicleID .. " changed paint slot " .. index)
+end
+```
+
+---
+
+#### `onVehicleReady(gameVehicleID)`
+
+当车辆的扩展设备加载完毕且车辆完全准备就绪时,就会发出此通知。
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**注意:**如果需要加载车辆扩展,请使用此方法代替`onVehicleSpawned` 。
+
+**用法:**
+
+```lua
+local originalOnVehicleReady = MPVehicleGE.onVehicleReady
+MPVehicleGE.onVehicleReady = function(gameVehicleID)
+ originalOnVehicleReady(gameVehicleID)
+
+ -- Safe to interact with vehicle extensions here
+ local veh = be:getObjectByID(gameVehicleID)
+ if veh then
+ veh:queueLuaCommand("print('Vehicle is ready!')")
+ end
+end
+```
+
+---
+
+#### `onUIInitialised()`
+
+在 BeamMP 用户界面初始化时调用
+
+**用法:**
+
+```lua
+local originalOnUIInitialised = MPVehicleGE.onUIInitialised
+MPVehicleGE.onUIInitialised = function()
+ originalOnUIInitialised()
+
+ print("BeamMP UI initialized")
+end
+```
+
+---
+
+#### `onSettingsChanged()`
+
+当 BeamMP 设置更改时调用
+
+**用法:**
+
+```lua
+local originalOnSettingsChanged = MPVehicleGE.onSettingsChanged
+MPVehicleGE.onSettingsChanged = function()
+ originalOnSettingsChanged()
+
+ print("BeamMP settings changed")
+end
+```
+
+---
+
+## MPConfig 函数
+
+### `MPConfig.getPlayerServerID()`
+
+返回本地玩家的服务器分配 ID
+
+**返回:**
+
+- (数字)- 玩家的服务器 ID(如果未设置则为 -1)
+
+**用法:**
+
+```lua
+local myID = extensions.MPConfig.getPlayerServerID()
+```
+
+---
+
+### `MPConfig.getNickname()`
+
+返回本地玩家的昵称
+
+**返回:**
+
+- (字符串)- 玩家当前的昵称
+
+**用法:**
+
+```lua
+local name = extensions.MPConfig.getNickname()
+```
+
+---
+
+### `MPConfig.getConfig()`
+
+返回 BeamMP 配置设置
+
+**返回:**
+
+- (表)- 包含所有 BeamMP 设置的配置表
+- (nil)- 如果配置文件不存在
+
+**用法:**
+
+```lua
+local config = extensions.MPConfig.getConfig()
+```
+
+---
+
+### `MPConfig.setConfig(settingName, settingVal)`
+
+设置特定配置值
+
+**参数:**
+
+- `settingName` (字符串)- 设置的名称
+- `settingVal` (任意值) - 要设置的值
+
+**用法:**
+
+```lua
+extensions.MPConfig.setConfig("myCustomSetting", true)
+```
+
+---
+
+## MPCoreNetwork 函数
+
+### `MPCoreNetwork.getCurrentServer()`
+
+返回有关当前连接服务器的信息
+
+**返回:**
+
+- (表)- 服务器数据(IP 地址、端口、名称、映射)
+- (nil)- 如果未连接
+
+**用法:**
+
+```lua
+local server = extensions.MPCoreNetwork.getCurrentServer()
+if server then
+ print("Server: " .. server.name)
+ print("IP: " .. server.ip .. ":" .. server.port)
+end
+```
+
+---
+
+## 事件系统功能
+
+### `TriggerServerEvent(name, data)`
+
+向服务器发送事件
+
+**参数:**
+
+- `name` (字符串)- 事件名称
+- `data` (字符串)- 要发送的数据
+
+**注意:**这是一个全局函数。服务器必须已注册此事件的处理程序。
+
+**用法:**
+
+```lua
+TriggerServerEvent("playerReady", "ready")
+
+-- With JSON
+local data = {position = {x=100, y=200, z=50}}
+TriggerServerEvent("updatePlayer", jsonEncode(data))
+```
+
+---
+
+### `TriggerClientEvent(name, data)`
+
+触发本地客户端事件
+
+**参数:**
+
+- `name` (字符串)- 事件名称
+- `data` (字符串)- 要发送的数据
+
+**注意:**全局函数。在本地触发,无需发送到服务器。
+
+**用法:**
+
+```lua
+TriggerClientEvent("localUpdate", "data")
+```
+
+---
+
+### `AddEventHandler(event_name, func, name)`
+
+注册一个用于处理特定事件的函数
+
+**参数:**
+
+- `event_name` (字符串)- 要处理的事件的名称
+- `func` (函数)- 处理函数(接收事件数据)
+- `name` (字符串)- 可选的内部名称
+
+**注意:**全局函数。
+
+**用法:**
+
+```lua
+AddEventHandler("playerDamage", function(data)
+ print("Damage: " .. data)
+end)
+
+-- With JSON
+AddEventHandler("vehicleSpawned", function(data)
+ local vehData = jsonDecode(data)
+ print("Spawned: " .. vehData.model)
+end)
+```
+
+---
+
+### `RemoveEventHandler(event_name, name)`
+
+移除事件处理程序
+
+**参数:**
+
+- `event_name` (字符串)- 事件名称
+- `name` (字符串)- 可选的内部名称
+
+**注意:**全局函数。
+
+**用法:**
+
+```lua
+RemoveEventHandler("playerDamage")
+```
+
+---
+
+## 按键功能
+
+### `onKeyPressed(keyname, func)`
+
+注册一个按键按下时要调用的函数
+
+**参数:**
+
+- `keyname` (字符串)- 按键的名称(例如,“NUMPAD1”、“F1”)
+- `func` (函数)- 要调用的函数(接收布尔值)
+
+**注意:**全局函数。
+
+**用法:**
+
+```lua
+onKeyPressed("NUMPAD1", function(state)
+ print("NUMPAD1 pressed!")
+end)
+```
+
+---
+
+### `onKeyReleased(keyname, func)`
+
+注册一个在按键释放时要调用的函数
+
+**参数:**
+
+- `keyname` (字符串)- 键的名称
+- `func` (函数)- 要调用的函数(接收布尔值)
+
+**注意:**全局函数。
+
+**用法:**
+
+```lua
+onKeyReleased("NUMPAD1", function(state)
+ print("NUMPAD1 released!")
+end)
+```
+
+---
+
+### `addKeyEventListener(keyname, func, type)`
+
+注册一个具有可自定义触发类型的按键事件监听器
+
+**参数:**
+
+- `keyname` (字符串)- 键的名称
+- `func` (函数)- 要调用的函数
+- `type` (字符串)- 事件类型:“向下”、“向上”或“两者”(默认值:“两者”)
+
+**注意:**全局函数。
+
+**用法:**
+
+```lua
+addKeyEventListener("F1", function(isPressed)
+ if isPressed then
+ print("F1 pressed")
+ else
+ print("F1 released")
+ end
+end, "both")
+```
+
+---
+
+### `getKeyState(keyname)`
+
+返回键的当前状态
+
+**参数:**
+
+- `keyname` (字符串)- 按键名称
+
+**返回:**
+
+- (布尔值)- 按下时为true,否则为false
+
+**注意:**全局函数。仅适用于通过 addKeyEventListener 注册的键。
+
+**用法:**
+
+```lua
+local isPressed = getKeyState("NUMPAD1")
+if isPressed then
+ print("NUMPAD1 is held down")
+end
+```
+
+---
+
+## UI 函数
+
+### `MPGameNetwork.spawnUiDialog(dialogInfo)`
+
+创建自定义交互式对话框
+
+**参数:**
+
+- `dialogInfo` (表)- 对话框配置:
+ - `title` (字符串)- 对话框标题(可选)
+ - `body` (字符串)- 对话框消息(可选)
+ - `buttons` (表) - 按钮配置(可选)
+ - `class` (字符串)- “experimental” 用于危险警示线(可选)
+ - `interactionID` (字符串)- 交互标识符(可选)
+ - `reportToServer` (布尔值)- 发送到服务器(可选,默认值:false)
+ - `reportToExtensions` (布尔值)- 触发本地事件(可选,默认值:false)
+
+**用法:**
+
+```lua
+-- Simple dialog
+extensions.MPGameNetwork.spawnUiDialog({
+ title = "Welcome",
+ body = "Welcome to the server!"
+})
+
+-- Choice dialog
+extensions.MPGameNetwork.spawnUiDialog({
+ title = "Choose Team",
+ body = "Which team?",
+ buttons = {
+ {label = "Red", key = "joinRed"},
+ {label = "Blue", key = "joinBlue"}
+ },
+ interactionID = "teamSelection",
+ reportToServer = true
+})
+```
+
+---
+
+## MPGameNetwork 回调
+
+### `MPGameNetwork.onUpdate(dt)`
+
+连接到多人游戏时,每一帧都会被调用
+
+**参数:**
+
+- `dt` (数值)- 时间差(秒)
+
+**用法:**
+
+```lua
+local originalOnUpdate = MPGameNetwork.onUpdate
+MPGameNetwork.onUpdate = function(dt)
+ originalOnUpdate(dt)
+ -- Your code here
+end
+```
+
+---
+
+### `MPGameNetwork.onVehicleReady(gameVehicleID)`
+
+当车辆准备就绪且扩展设备已加载完毕时,会发出呼叫。
+
+**参数:**
+
+- `gameVehicleID` (数字)- 游戏内部车辆 ID
+
+**用法:**
+
+```lua
+local originalOnVehicleReady = MPGameNetwork.onVehicleReady
+MPGameNetwork.onVehicleReady = function(gameVehicleID)
+ originalOnVehicleReady(gameVehicleID)
+ -- Your code here
+end
+```
+
+---
+
+## 编码函数
+
+### `MPHelpers.b64encode(string)`
+
+将字符串编码为 Base64(RFC 2045)
+
+**参数:**
+
+- `string` (字符串)- 要编码的字符串
+
+**返回:**
+
+- (字符串)- Base64 编码的字符串
+
+**用法:**
+
+```lua
+local encoded = extensions.MPHelpers.b64encode("Hello World")
+
+-- Encoding JSON
+local data = {name = "Player", score = 100}
+local encoded = extensions.MPHelpers.b64encode(jsonEncode(data))
+TriggerServerEvent("sendData", encoded)
+```
+
+---
+
+### `MPHelpers.b64decode(string)`
+
+解码 Base64 字符串(RFC 2045)
+
+**参数:**
+
+- `string` (string)- Base64 编码的字符串
+
+**返回:**
+
+- (字符串)- 解码后的字符串
+
+**用法:**
+
+```lua
+local decoded = extensions.MPHelpers.b64decode("SGVsbG8gV29ybGQ=")
+
+-- Decoding JSON
+AddEventHandler("receiveData", function(data)
+ local decoded = extensions.MPHelpers.b64decode(data)
+ local jsonData = jsonDecode(decoded)
+end)
+```
+
+---
+
+## 颜色函数
+
+### `MPHelpers.hex2rgb(hex)`
+
+将十六进制颜色代码转换为 RGB 值
+
+**参数:**
+
+- `hex` (字符串)- 十六进制颜色代码(例如,“#FF5733”或“#F57”)
+
+**返回:**
+
+- (表)- RGB 值`{r, g, b}`范围为 0-1
+- (表)- 如果无效则为`{0, 0, 0}`
+
+**注意:**支持 3 位和 6 位十六进制代码。
+
+**用法:**
+
+```lua
+local rgb = extensions.MPHelpers.hex2rgb("#FF5733")
+print(rgb[1], rgb[2], rgb[3]) -- 1.0, 0.341, 0.2
+
+-- Short format
+local rgb = extensions.MPHelpers.hex2rgb("#F57")
+```
+
+---
+
+## 字符串函数
+
+### `MPHelpers.splitStringToTable(string, delimiter, convert_into)`
+
+按分隔符拆分字符串,并可选择转换值
+
+**参数:**
+
+- `string` (字符串)- 要拆分的字符串
+- `delimiter` (字符串) - 用于分割的分隔符
+- `convert_into` (number) - 转换类型(可选):
+ - `nil`或`0` - 保留为字符串(默认值)
+ - `1` - 转换为数字
+ - `2` - 转换为布尔值
+
+**返回:**
+
+- (表)- 分割值的数组
+
+**用法:**
+
+```lua
+-- Strings
+local parts = extensions.MPHelpers.splitStringToTable("Hello,World", ",")
+-- {"Hello", "World"}
+
+-- Numbers
+local nums = extensions.MPHelpers.splitStringToTable("10,20,30", ",", 1)
+-- {10, 20, 30}
+
+-- Parse coordinates
+local coords = extensions.MPHelpers.splitStringToTable("100,200,50", ",", 1)
+local x, y, z = coords[1], coords[2], coords[3]
+```
+
+---
+
+## 表函数
+
+### `MPHelpers.tableDiff(old, new)`
+
+比较两个表并返回它们的差异
+
+**参数:**
+
+- `old`表 - 要比较的第一个表
+- `new` (表)——第二个用于比较的表
+
+**返回:**
+
+- (表) `diff` - 所有不同的键
+- (表) `o` - 与旧值不同的值
+- (表) `n` - 与新值不同的数值
+
+**用法:**
+
+```lua
+local oldConfig = {speed = 100, damage = 50, armor = 30}
+local newConfig = {speed = 120, damage = 50, armor = 40}
+
+local diff, oldVals, newVals = extensions.MPHelpers.tableDiff(oldConfig, newConfig)
+-- diff = {speed = 120, armor = 40}
+
+for key, value in pairs(diff) do
+ print(key .. " changed from " .. oldVals[key] .. " to " .. newVals[key])
+end
+```
+
+---
+
+## 调试函数
+
+### `MPHelpers.simpletraces(level)`
+
+返回格式化的调用者信息字符串。
+
+**参数:**
+
+- `level` (数字)- 堆栈层级(可选,默认值:2)
+
+**返回:**
+
+- (字符串)- 格式化字符串: `"source:line, namewhat name"`
+- (字符串)- 如果信息不可用,则为`"unknown"`
+
+**用法:**
+
+```lua
+local function myFunction()
+ local caller = extensions.MPHelpers.simpletraces()
+ print("Called from: " .. caller)
+end
+```
+
+---
+
+### `MPHelpers.simpletrace(level)`
+
+将调用者信息记录到控制台
+
+**参数:**
+
+- `level` (数字)- 堆栈层级(可选,默认值:1)
+
+**注意:**将调用位置记录到控制台。
+
+**用法:**
+
+```lua
+local function myFunction()
+ extensions.MPHelpers.simpletrace()
+ -- Logs: "Code was called from: lua/ge/extensions/mymod.lua:42"
+end
+```
+
+---
+
+*最后更新日期:2026年1月1日*
diff --git a/docs/zh/API documentation/Server-Side.md b/docs/zh/API documentation/Server-Side.md
new file mode 100644
index 00000000..73f5cf3f
--- /dev/null
+++ b/docs/zh/API documentation/Server-Side.md
@@ -0,0 +1,1549 @@
+## 目录
+
+### 全局
+
+- [全局函数](#global-functions)
+
+### MP
+
+- [玩家](#mp--players)
+- [车辆](#mp--vehicles)
+- [通信](#mp--communication)
+- [事件](#mp--events)
+- [工具](#mp--utilities)
+
+### Util
+
+- [日志记录](#util--logging)
+- [JSON](#util--json)
+- [随机数](#util--random)
+- [性能分析](#util--profiling)
+
+### Http
+
+- [HTTP 函数](#http)
+
+### FS
+
+- [检查](#fs--checks)
+- [操作](#fs--operations)
+- [路径](#fs--paths)
+
+### 事件
+
+- [事件参考](#events)
+
+---
+
+## 全局函数
+
+### `print(...)`
+
+打印到服务器控制台,以日期、时间和`[LUA]`为前缀。
+
+**参数:**
+
+- `...` (任意)——任何类型的值。表会连同其内容一起打印出来。
+
+**用法:**
+
+```lua
+local name = "John Doe"
+print("Hello, I'm", name, "and I'm", 32)
+```
+
+---
+
+### `printRaw(...)`
+
+不带任何前缀直接打印到服务器控制台。
+
+**参数:**
+
+- `...` (任意)——任何类型的值。
+
+---
+
+### `exit()`
+
+正常关闭服务器。触发`onShutdown`事件。
+
+---
+
+## MP — 玩家
+
+### `MP.GetPlayerCount() -> number`
+
+返回当前在线玩家的数量。
+
+**返回:**
+
+- (数字)- 玩家人数。
+
+---
+
+### `MP.GetPlayers() -> table`
+
+返回所有已连接玩家的表。
+
+**返回:**
+
+- (表)- `{[playerID] = playerName}`的映射。
+
+---
+
+### `MP.GetPlayerName(playerID) -> string`
+
+根据ID返回玩家名称。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+
+**返回:**
+
+- (字符串)- 玩家名称,如果找不到则为`""` 。
+
+**用法:**
+
+```lua
+local player_id = 4
+print(MP.GetPlayerName(player_id))
+```
+
+---
+
+### `MP.GetPlayerIDByName(name) -> number`
+
+根据名称返回玩家的 ID。
+
+**参数:**
+
+- `name` (字符串)- 玩家的名称。
+
+**返回:**
+
+- (数字)- 玩家 ID,如果找不到则为`-1` 。
+
+---
+
+### `MP.GetPlayerIdentifiers(playerID) -> table`
+
+返回玩家的标识符,例如 IP 地址、BeamMP 论坛 ID 和 Discord ID。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+
+**返回:**
+
+- (表)- 包含键`ip` 、 `beammp` 、 `discord` (仅当已链接时)的表。
+- (nil)- 如果未找到玩家。
+
+**用法:**
+
+```lua
+local player_id = 5
+print(MP.GetPlayerIdentifiers(player_id))
+-- { ip: "127.0.0.1", discord: "12345678987654321", beammp: "1234567" }
+```
+
+---
+
+### `MP.GetPlayerRole(playerID) -> string|nil`
+
+返回玩家在 BeamMP 后端设置的角色。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+
+**返回:**
+
+- (字符串)- 玩家的角色。
+- (nil)- 如果未找到玩家。
+
+---
+
+### `MP.IsPlayerConnected(playerID) -> boolean`
+
+返回是否已收到来自玩家的 UDP 数据包,即连接是否已完全建立。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+
+**返回:**
+
+- (布尔值)- 如果完全连接, `true` 。
+
+**用法:**
+
+```lua
+local player_id = 8
+print(MP.IsPlayerConnected(player_id))
+```
+
+---
+
+### `MP.IsPlayerGuest(playerID) -> boolean`
+
+返回玩家是否为访客(未在 BeamMP 论坛注册)。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+
+**返回:**
+
+- (布尔值)- 如果是访客`true` 。
+
+---
+
+### `MP.DropPlayer(playerID, reason?)`
+
+将玩家踢出服务器。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+- `reason` (字符串,可选)- 被踢的原因。
+
+**用法:**
+
+```lua
+function ChatHandler(player_id, player_name, message)
+ if string.match(message, "darn") then
+ MP.DropPlayer(player_id, "Profanity is not allowed")
+ return 1
+ end
+end
+```
+
+---
+
+## MP — 车辆
+
+### `MP.GetPlayerVehicles(playerID) -> table`
+
+返回玩家的所有车辆。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+
+**返回:**
+
+- (表)- `{[vehicleID] = dataString}`的映射,其中 dataString 是原始 JSON 字符串。
+- (nil)- 如果玩家没有车辆或未被找到。
+
+**用法:**
+
+```lua
+local player_id = 3
+local player_vehicles = MP.GetPlayerVehicles(player_id)
+
+for vehicle_id, vehicle_data in pairs(player_vehicles) do
+ local start = string.find(vehicle_data, "{")
+ local formattedVehicleData = string.sub(vehicle_data, start, -1)
+ print(Util.JsonDecode(formattedVehicleData))
+end
+```
+
+---
+
+### `MP.GetPositionRaw(playerID, vehicleID) -> table, string`
+
+返回车辆的当前原始位置。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+- `vehicleID` (number)- 车辆的 ID。
+
+**返回:**
+
+- (表)- 包含以下键的表: `pos` 、 `rot` 、 `vel` 、 `rvel` 、 `tim` 、 `ping` 。
+- (字符串)- 如果发生错误,则显示错误信息;成功时显示空字符串。
+
+**注意:** `pos` 、 `rot` 、 `vel` 、 `rvel`中的每个值都是一个表,索引为`1, 2, 3` ( `rot`的索引为`4` )。
+
+**用法:**
+
+```lua
+local player_id = 4
+local vehicle_id = 0
+
+local raw_pos, error = MP.GetPositionRaw(player_id, vehicle_id)
+if error == "" then
+ local x, y, z = table.unpack(raw_pos["pos"])
+ print("X:", x, "Y:", y, "Z:", z)
+else
+ print(error)
+end
+```
+
+---
+
+### `MP.RemoveVehicle(playerID, vehicleID)`
+
+移除玩家拥有的车辆。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID。
+- `vehicleID` (number)- 车辆的 ID。
+
+**用法:**
+
+```lua
+local player_id = 3
+local player_vehicles = MP.GetPlayerVehicles(player_id)
+
+for vehicle_id, vehicle_data in pairs(player_vehicles) do
+ MP.RemoveVehicle(player_id, vehicle_id)
+end
+```
+
+---
+
+## MP — 通讯
+
+### `MP.SendChatMessage(playerID, message, logChat?)`
+
+向特定玩家或所有人发送聊天消息。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID, `-1`表示所有人。
+- `message` (字符串)- 消息内容。
+- `logChat` (布尔值,可选)- 是否记录到服务器日志(默认值: `true` )。
+
+**注意:**此函数不返回值。
+
+**用法:**
+
+```lua
+-- To a specific player
+function ChatHandler(player_id, player_name, msg)
+ if string.match(msg, "darn") then
+ MP.SendChatMessage(player_id, "Please do not use profanity.")
+ return 1
+ end
+end
+
+-- To everyone
+MP.SendChatMessage(-1, "Hello World!")
+```
+
+---
+
+### `MP.SendNotification(playerID, message, icon?, category?)`
+
+向特定玩家或所有玩家发送通知(弹出窗口)。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID, `-1`表示所有人。
+- `message` (字符串)- 通知内容。
+- `icon` (字符串,可选)- 通知图标。
+- `category` (字符串,可选)- 通知类别。
+
+**注意:**此函数不返回值。当仅使用 3 个参数(不指定类别)调用时,类别会自动设置为消息的值。
+
+---
+
+### `MP.ConfirmationDialog(playerID, title, body, buttons, interactionID, warning?, reportToServer?, reportToExtensions?)`
+
+向玩家发送带有按钮的确认对话框。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID, `-1`表示所有人。
+- `title` (字符串)- 对话框标题。
+- `body` (字符串)- 对话框正文。
+- `buttons` (表)- 按钮数组。
+- `interactionID` (字符串)- 此交互的唯一标识符。
+- `warning` (布尔值,可选)- 显示警告样式(默认值: `false` )。
+- `reportToServer` (布尔值,可选)- 向服务器发送响应(默认值: `true` )。
+- `reportToExtensions` (布尔值,可选)- 触发本地事件(默认值: `true` )。
+
+**注意:**当只使用 5 个参数调用该函数时,该函数不返回值。当使用 6-8 个参数调用该函数时,它会返回`boolean, string` 。
+
+---
+
+### `MP.TriggerClientEvent(playerID, eventName, data) -> boolean, string`
+
+将事件发送给特定客户端或所有人。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID, `-1`表示所有人。
+- `eventName` (字符串)- 事件名称。
+- `data` (字符串)- 要发送的数据。
+
+**返回:**
+
+- (布尔值)- 如果发送成功则为`true` `-1`始终为`true` 。
+- (字符串)- 如果失败,则显示错误消息。
+
+---
+
+### `MP.TriggerClientEventJson(playerID, eventName, data) -> boolean, string`
+
+与`TriggerClientEvent`相同,但接受 Lua 表并自动将其编码为 JSON。
+
+**参数:**
+
+- `playerID` (数字)- 玩家的 ID, `-1`表示所有人。
+- `eventName` (字符串)- 事件名称。
+- `data` (表) - 要进行 JSON 编码并发送的 Lua 表。
+
+**返回:**
+
+- (布尔值)- 成功时为`true` 。
+- (字符串)- 如果失败,则显示错误消息。
+
+---
+
+## MP — 事件
+
+### `MP.RegisterEvent(eventName, functionName)`
+
+将函数注册为事件的处理程序。
+
+**参数:**
+
+- `eventName` (字符串)- 事件名称。
+- `functionName` (字符串)- 要注册的 Lua 函数的名称。
+
+**注意:**如果事件不存在,则会创建该事件。可以为同一个事件注册多个处理程序。
+
+**用法:**
+
+```lua
+function ChatHandler(player_id, player_name, msg)
+ if msg == "hello" then
+ print("Hello World!")
+ return 0
+ end
+end
+
+MP.RegisterEvent("onChatMessage", "ChatHandler")
+```
+
+---
+
+### `MP.TriggerLocalEvent(eventName, ...) -> table`
+
+仅在当前状态下触发事件。同步。
+
+**参数:**
+
+- `eventName` (字符串)- 事件名称。
+- `...` (任意,可选)——传递给处理程序的参数。
+
+**返回:**
+
+- (表)- 所有处理程序的返回值表。
+
+**用法:**
+
+```lua
+local Results = MP.TriggerLocalEvent("MyEvent")
+print(Results)
+```
+
+---
+
+### `MP.TriggerGlobalEvent(eventName, ...) -> table`
+
+在所有状态下触发事件。异步执行。本地处理程序同步且立即运行。
+
+**参数:**
+
+- `eventName` (字符串)- 事件名称。
+- `...` (任意,可选)- 参数。支持的类型:字符串、数字、布尔值、表。
+
+**返回:**
+
+- (表)- 类似 Future 的对象,包含:
+ - `:IsDone() -> boolean` — 所有处理程序是否已完成。
+ - `:GetResults() -> table` — 返回所有处理程序的值。
+
+**注意:**调用这些方法时要用冒号`:`不要用句点`.` 。
+
+**用法:**
+
+```lua
+local Future = MP.TriggerGlobalEvent("MyEvent")
+while not Future:IsDone() do
+ MP.Sleep(100)
+end
+local Results = Future:GetResults()
+print(Results)
+```
+
+---
+
+### `MP.CreateEventTimer(eventName, intervalMS, strategy?)`
+
+创建一个定时器,重复触发一个事件。
+
+**参数:**
+
+- `eventName` (字符串)- 要触发的事件。
+- `intervalMS` (数值)- 触发之间的间隔,以毫秒为单位。
+- `strategy` (数字,可选)- `MP.CallStrategy.BestEffort` (默认值)或`MP.CallStrategy.Precise` 。
+
+**注意:**不建议使用低于 25 毫秒的间隔,且服务可能无法稳定运行。
+
+**用法:**
+
+```lua
+local seconds = 0
+
+function CountSeconds()
+ seconds = seconds + 1
+end
+
+MP.RegisterEvent("EverySecond", "CountSeconds")
+MP.CreateEventTimer("EverySecond", 1000)
+```
+
+---
+
+### `MP.CancelEventTimer(eventName)`
+
+取消已存在的事件计时器。
+
+**参数:**
+
+- `eventName` (字符串)- 事件名称。
+
+**注意:**由于异步行为,该事件在被取消之前可能会再次触发一次。
+
+---
+
+## MP — 工具
+
+### `MP.CreateTimer() -> table`
+
+创建一个计时器对象,用于测量经过的时间。
+
+**返回:**
+
+- (表)- 对象包含:
+ - `:GetCurrent() -> float` — 自上次开始以来经过的秒数。
+ - `:Start()` — 重置计时器。
+
+**用法:**
+
+```lua
+local mytimer = MP.CreateTimer()
+-- do stuff here that needs to be timed
+print(mytimer:GetCurrent())
+```
+
+---
+
+### `MP.GetOSName() -> string`
+
+返回服务器操作系统的名称。
+
+**返回:**
+
+- (字符串)- `"Windows"` 、 `"Linux"`或`"Other"` 。
+
+---
+
+### `MP.GetServerVersion() -> number, number, number`
+
+返回服务器版本。
+
+**返回:**
+
+- (数字)- 主要
+- (数字)- 次要
+- (number)- 补丁
+
+**用法:**
+
+```lua
+local major, minor, patch = MP.GetServerVersion()
+print(major, minor, patch)
+```
+
+---
+
+### `MP.Get(configID) -> value`
+
+通过 ID 读取服务器配置设置。
+
+**参数:**
+
+- `configID` (数字)- 来自`MP.Settings`的 ID。
+
+**返回:**
+
+- (值)- 设置的当前值。
+
+---
+
+### `MP.Set(configID, value)`
+
+临时更改服务器配置设置。更改不会保存到配置文件中。
+
+**参数:**
+
+- `configID` (数字)- 来自`MP.Settings`的 ID。
+- `value` (任意)- 新值。类型必须与设置匹配。
+
+**用法:**
+
+```lua
+MP.Set(MP.Settings.Debug, true)
+```
+
+---
+
+### `MP.Settings`
+
+用于`MP.Get`和`MP.Set`设置 ID 枚举。
+
+```lua
+MP.Settings.Debug -- 0 (boolean)
+MP.Settings.Private -- 1 (boolean)
+MP.Settings.MaxCars -- 2 (number)
+MP.Settings.MaxPlayers -- 3 (number)
+MP.Settings.Map -- 4 (string)
+MP.Settings.Name -- 5 (string)
+MP.Settings.Description -- 6 (string)
+MP.Settings.InformationPacket -- 7 (boolean)
+```
+
+---
+
+### `MP.CallStrategy`
+
+用于`MP.CreateEventTimer`枚举。
+
+```lua
+MP.CallStrategy.BestEffort -- Skip trigger if previous handler hasn't finished (default)
+MP.CallStrategy.Precise -- Always trigger, even if it causes the queue to build up
+```
+
+---
+
+### `MP.Sleep(ms)`
+
+暂停当前 Lua 状态若干毫秒。
+
+**参数:**
+
+- `ms` (数字)- 睡眠时间(以毫秒为单位)。
+
+**注意:**睡眠状态下不会执行任何操作。如果注册了事件处理程序,**请勿让服务器睡眠超过 500 毫秒**——睡眠状态会显著降低整个服务器的运行速度。
+
+**用法:**
+
+```lua
+local Future = MP.TriggerGlobalEvent("MyEvent")
+while not Future:IsDone() do
+ MP.Sleep(100)
+end
+```
+
+---
+
+### `MP.GetStateMemoryUsage() -> number`
+
+返回当前 Lua 状态的内存使用情况。
+
+**返回:**
+
+- (数字)- 内存大小(以字节为单位)。
+
+---
+
+### `MP.GetLuaMemoryUsage() -> number`
+
+返回所有 Lua 状态的总内存使用量。
+
+**返回:**
+
+- (数字)- 内存大小(以字节为单位)。
+
+---
+
+## Util — 日志记录
+
+### `Util.LogInfo(...)` 、 `Util.LogWarn(...)` 、 `Util.LogError(...)` 、 `Util.LogDebug(...)`
+
+在相应级别的服务器日志中打印信息。
+
+**参数:**
+
+- `...` (任意)——任何类型的值。
+
+**注意:**仅当启用`MP.Settings.Debug`时才会显示`Util.LogDebug` 。
+
+**用法:**
+
+```lua
+Util.LogInfo("Hello, World!")
+Util.LogWarn("Cool warning")
+Util.LogError("Oh no!")
+Util.LogDebug("hi")
+```
+
+---
+
+## Util — JSON
+
+### `Util.JsonEncode(table) -> string`
+
+将 Lua 表编码为 JSON 字符串。
+
+**参数:**
+
+- `table` (table) - 要编码的表。
+
+**返回:**
+
+- (字符串)- 压缩后的 JSON 字符串。
+
+**注意:**根据键类型自动检测数组还是对象。函数、用户数据和不支持的类型将被忽略。
+
+**用法:**
+
+```lua
+local player = {
+ name = "Lion",
+ age = 69,
+ skills = { "skill A", "skill B" }
+}
+local json = Util.JsonEncode(player)
+-- '{"name":"Lion","age":69,"skills":["skill A","skill B"]}'
+```
+
+---
+
+### `Util.JsonDecode(json) -> table`
+
+将 JSON 字符串解码为 Lua 表。
+
+**参数:**
+
+- `json` (字符串)- 有效的 JSON 字符串。
+
+**返回:**
+
+- (表)——解码后的表。
+- (nil)- 如果 JSON 无效。
+
+**用法:**
+
+```lua
+local json = "{\"message\":\"OK\",\"code\":200}"
+local tbl = Util.JsonDecode(json)
+-- { message = "OK", code = 200 }
+```
+
+---
+
+### `Util.JsonPrettify(json) -> string`
+
+为 JSON 字符串添加缩进和换行符,以提高可读性(缩进为 4)。
+
+**参数:**
+
+- `json` (字符串)- 有效的 JSON 字符串。
+
+**返回:**
+
+- (字符串)- 美化打印的 JSON。
+
+**用法:**
+
+```lua
+local myjson = Util.JsonEncode({ name="Lion", age = 69, skills = { "skill A", "skill B" } })
+print(Util.JsonPrettify(myjson))
+```
+
+---
+
+### `Util.JsonMinify(json) -> string`
+
+从 JSON 字符串中删除不必要的空格和换行符。
+
+**参数:**
+
+- `json` (字符串)- 有效的 JSON 字符串。
+
+**返回:**
+
+- (字符串)- 压缩后的 JSON。
+
+**用法:**
+
+```lua
+local pretty = Util.JsonPrettify(Util.JsonEncode({ name="Lion", age = 69 }))
+print(Util.JsonMinify(pretty))
+```
+
+---
+
+### `Util.JsonFlatten(json) -> string`
+
+根据 RFC 6901 将嵌套的 JSON 扁平化为`/a/b/c`样式的键。
+
+**参数:**
+
+- `json` (字符串)- 有效的 JSON 字符串。
+
+**返回:**
+
+- (字符串)- 扁平化的 JSON。
+
+**用法:**
+
+```lua
+local json = Util.JsonEncode({ name="Lion", skills = { "skill A", "skill B" } })
+print(Util.JsonFlatten(json))
+-- '{"/name":"Lion","/skills/0":"skill A","/skills/1":"skill B"}'
+```
+
+---
+
+### `Util.JsonUnflatten(json) -> string`
+
+将扁平化的 JSON 恢复到其嵌套结构。
+
+**参数:**
+
+- `json` (字符串)- 扁平化的 JSON 字符串。
+
+**返回:**
+
+- (字符串)- 嵌套 JSON。
+
+---
+
+### `Util.JsonDiff(a, b) -> string`
+
+根据 RFC 6902 计算两个 JSON 字符串之间的差异。
+
+**参数:**
+
+- `a` (字符串)- 第一个 JSON 字符串。
+- `b` (字符串)- 第二个 JSON 字符串。
+
+**返回:**
+
+- (字符串)- 表示差异的 JSON 补丁。
+
+---
+
+## Util — 随机
+
+### `Util.Random() -> float`
+
+返回一个介于 0 和 1 之间的随机浮点数。
+
+**返回:**
+
+- (float)
+
+**用法:**
+
+```lua
+local rand = Util.Random()
+print("rand: " .. rand)
+-- rand: 0.135477
+```
+
+---
+
+### `Util.RandomRange(min, max) -> float`
+
+返回给定范围内的随机浮点数。
+
+**参数:**
+
+- `min` (数字)- 下限。
+- `max` (数字)- 上限。
+
+**返回:**
+
+- (float)
+
+**用法:**
+
+```lua
+local randFloat = Util.RandomRange(1, 1000)
+print("randFloat: " .. randFloat)
+-- randFloat: 420.6969
+```
+
+---
+
+### `Util.RandomIntRange(min, max) -> number`
+
+返回给定范围内的随机整数。
+
+**参数:**
+
+- `min` (数字)- 下限。
+- `max` (数字)- 上限。
+
+**返回:**
+
+- (数字)- 整数。
+
+**用法:**
+
+```lua
+local randInt = Util.RandomIntRange(1, 100)
+print("randInt: " .. randInt)
+-- randInt: 69
+```
+
+---
+
+## Util — 分析
+
+### `Util.DebugStartProfile(name)`
+
+启动一个命名执行时间测量。
+
+**参数:**
+
+- `name` (字符串)- 此测量的标识符。
+
+---
+
+### `Util.DebugStopProfile(name)`
+
+停止指定名称的测量。必须在调用`DebugStartProfile`之后,并使用相同的名称调用此函数。
+
+**参数:**
+
+- `name` (字符串)- 此测量的标识符。
+
+---
+
+### `Util.DebugExecutionTime() -> table`
+
+返回每个已运行处理程序的执行时间统计信息。
+
+**返回:**
+
+- (表)- 每个处理程序: `mean` 、 `stdev` 、 `min` 、 `max` 、 `n` (全部以毫秒为单位)。
+
+**用法:**
+
+```lua
+function printDebugExecutionTime()
+ local stats = Util.DebugExecutionTime()
+ local pretty = "DebugExecutionTime:\n"
+ local longest = 0
+ for name, t in pairs(stats) do
+ if #name > longest then
+ longest = #name
+ end
+ end
+ for name, t in pairs(stats) do
+ pretty = pretty .. string.format("%" .. longest + 1 .. "s: %12f +/- %12f (min: %12f, max: %12f) (called %d time(s))\n", name, t.mean, t.stdev, t.min, t.max, t.n)
+ end
+ print(pretty)
+end
+```
+
+---
+
+## Http
+
+### `Http.CreateConnection(host, port) -> table`
+
+创建与外部服务器的HTTP连接。
+
+**参数:**
+
+- `host` (字符串)- 服务器地址。
+- `port` (number)- 端口号。
+
+**返回:**
+
+- (表)- 具有方法的连接对象`:Get(path, headers)` 。
+
+---
+
+### `connection:Get(path, headers)`
+
+发送HTTP GET请求。
+
+**参数:**
+
+- `path` (字符串)- 请求路径。
+- `headers` (表)- 表头作为`{[string] = string}` 。
+
+---
+
+## FS — 检查
+
+### `FS.Exists(path) -> boolean`
+
+返回路径是否存在。
+
+**参数:**
+
+- `path` (字符串)- 要检查的路径。
+
+**返回:**
+
+- (布尔值)- 如果存在`true` 。
+
+---
+
+### `FS.IsDirectory(path) -> boolean`
+
+返回指定路径是否为目录。
+
+**参数:**
+
+- `path` (字符串)- 要检查的路径。
+
+**返回:**
+
+- (布尔值)- 如果目录为`true` 。
+
+**注意:** `false`并不意味着该路径就是一个文件。请使用`FS.IsFile`单独进行检查。
+
+---
+
+### `FS.IsFile(path) -> boolean`
+
+返回指定路径是否为普通文件。
+
+**参数:**
+
+- `path` (字符串)- 要检查的路径。
+
+**返回:**
+
+- (布尔值)- 如果是普通文件`true` 。
+
+**注意:** `false`并不意味着该路径是一个目录。
+
+---
+
+## FS — 操作
+
+### `FS.CreateDirectory(path) -> boolean, string`
+
+创建目录,包括任何缺失的父目录(类似于`mkdir -p` )。
+
+**参数:**
+
+- `path` (字符串)- 要创建的目录的路径。
+
+**返回:**
+
+- (布尔值)- 成功时为`true` 。
+- (字符串)- 失败时显示错误消息,成功时显示`""` 。
+
+**用法:**
+
+```lua
+local success, error_message = FS.CreateDirectory("data/mystuff/somefolder")
+
+if not success then
+ print("failed to create directory: " .. error_message)
+end
+```
+
+---
+
+### `FS.Remove(path) -> boolean, string`
+
+删除文件或空目录。
+
+**参数:**
+
+- `path` (字符串)- 要删除的路径。
+
+**返回:**
+
+- (布尔值)- 成功时为`true` 。
+- (字符串)- 失败时的错误信息。
+
+---
+
+### `FS.Rename(path, newPath) -> boolean, string`
+
+重命名或移动文件或目录。
+
+**参数:**
+
+- `path` (字符串)- 当前路径。
+- `newPath` (字符串)- 新路径。
+
+**返回:**
+
+- (布尔值)- 成功时为`true` 。
+- (字符串)- 失败时的错误信息。
+
+---
+
+### `FS.Copy(path, newPath) -> boolean, string`
+
+复制文件或目录(递归)。
+
+**参数:**
+
+- `path` (字符串)- 源路径。
+- `newPath` (字符串)- 目标路径。
+
+**返回:**
+
+- (布尔值)- 成功时为`true` 。
+- (字符串)- 失败时的错误信息。
+
+---
+
+### `FS.ListFiles(path) -> table`
+
+返回目录中的文件名列表(非递归)。
+
+**参数:**
+
+- `path` (字符串)- 目录路径。
+
+**返回:**
+
+- (表)- 文件名数组。
+- (nil)- 如果路径不存在。
+
+**用法:**
+
+```lua
+print(FS.ListFiles("Resources/Server/examplePlugin"))
+-- { 1: "example.json", 2: "example.lua" }
+```
+
+---
+
+### `FS.ListDirectories(path) -> table`
+
+返回目录内所有目录名称的列表(非递归)。
+
+**参数:**
+
+- `path` (字符串)- 目录路径。
+
+**返回:**
+
+- (表格)- 目录名称数组。
+- (nil)- 如果路径不存在。
+
+**用法:**
+
+```lua
+print(FS.ListDirectories("Resources"))
+-- { 1: "Client", 2: "Server" }
+```
+
+---
+
+## FS — 路径
+
+### `FS.GetFilename(path) -> string`
+
+从指定路径返回带扩展名的文件名。
+
+**参数:**
+
+- `path` (字符串)- 路径字符串。
+
+**返回:**
+
+- (字符串)- 文件名。
+
+**用法:**
+
+```lua
+"my/path/a.txt" -> "a.txt"
+"somefile.txt" -> "somefile.txt"
+"/awesome/path" -> "path"
+```
+
+---
+
+### `FS.GetExtension(path) -> string`
+
+返回包含点号的文件扩展名。
+
+**参数:**
+
+- `path` (字符串)- 路径字符串。
+
+**返回:**
+
+- (字符串)- 扩展名(例如`".json"` ),如果没有扩展名,则为`""` 。
+
+**用法:**
+
+```lua
+"myfile.txt" -> ".txt"
+"somefile." -> "."
+"/awesome/path" -> ""
+"/awesome/path/file.zip.txt" -> ".txt"
+```
+
+---
+
+### `FS.GetParentFolder(path) -> string`
+
+返回包含目录的路径。
+
+**参数:**
+
+- `path` (字符串)- 路径字符串。
+
+**返回:**
+
+- (字符串)- 父文件夹路径。
+
+**用法:**
+
+```lua
+"/var/tmp/example.txt" -> "/var/tmp"
+"/" -> "/"
+"mydir/a/b/c.txt" -> "mydir/a/b"
+```
+
+---
+
+### `FS.ConcatPaths(...) -> string`
+
+使用系统首选分隔符将路径段连接起来,并解析存在的`..`分隔符。
+
+**参数:**
+
+- `...` (字符串)- 路径段。
+
+**返回:**
+
+- (字符串)- 连接路径。
+
+**用法:**
+
+```lua
+FS.ConcatPaths("a", "b", "/c/d/e/", "/f/", "g", "h.txt")
+-- "a/b/c/d/e/f/g/h.txt"
+```
+
+---
+
+## 事件
+
+### 玩家连接顺序
+
+```
+onPlayerAuth → onPlayerConnecting → onPlayerJoining → onPlayerJoin
+```
+
+---
+
+### `onInit`
+
+插件文件全部加载完毕后立即触发。
+
+**参数:**无**可取消:**否
+
+---
+
+### `onConsoleInput`
+
+当服务器控制台收到输入时触发。
+
+**参数:**
+
+- `input` (字符串)- 输入的文本。
+
+**可取消:**否
+
+**用法:**
+
+```lua
+function handleConsoleInput(cmd)
+ local delim = cmd:find(' ')
+ if delim then
+ local message = cmd:sub(delim+1)
+ if cmd:sub(1, delim-1) == "print" then
+ return message
+ end
+ end
+end
+
+MP.RegisterEvent("onConsoleInput", "handleConsoleInput")
+```
+
+---
+
+### `onShutdown`
+
+服务器关闭且所有玩家都被踢出后触发。
+
+**参数:**无**可取消:**否
+
+---
+
+### `onPlayerAuth`
+
+当玩家尝试连接时触发,在任何其他连接事件之前触发。
+
+**参数:**
+
+- `name` (字符串)- 玩家名称。
+- `role` (字符串)- 后端玩家角色。
+- `isGuest` (布尔值)- 玩家是否为访客。
+- `identifiers` (表) - 标识符: `ip` 、 `beammp` 、 `discord` 。
+
+**可取消:**是
+
+- 返回`1` — 以通用消息拒绝。
+- 返回`string` ——拒绝,拒绝理由为该字符串。
+- 返回`2` — 即使服务器已满也允许进入。
+
+**用法:**
+
+```lua
+function myPlayerAuthorizer(name, role, is_guest, identifiers)
+ return "Sorry, you cannot join at this time."
+end
+
+MP.RegisterEvent("onPlayerAuth", "myPlayerAuthorizer")
+```
+
+---
+
+### `postPlayerAuth`
+
+无论玩家是否被接受或拒绝,都会在`onPlayerAuth`之后触发。
+
+**参数:**
+
+- `wasRejected` (布尔值)- 玩家是否被拒绝。
+- `reason` (字符串)- 如果被拒绝,则显示拒绝原因。
+- `name` (字符串)- 玩家名称。
+- `role` (字符串)- 玩家角色。
+- `isGuest` (布尔值)- 是否为访客。
+- `identifiers` (表)- 标识符。
+
+**可取消:**否
+
+---
+
+### `onPlayerConnecting`
+
+当玩家开始连接时触发,在`onPlayerAuth`之后。
+
+**参数:**
+
+- `playerID` (数字)
+
+**可取消:**否
+
+---
+
+### `onPlayerJoining`
+
+玩家完成所有模组下载后触发。
+
+**参数:**
+
+- `playerID` (数字)
+
+**可取消:**否
+
+---
+
+### `onPlayerJoin`
+
+玩家完成同步并进入游戏后触发。
+
+**参数:**
+
+- `playerID` (数字)
+
+**可取消:**否
+
+---
+
+### `onPlayerDisconnect`
+
+当玩家断开连接时触发。
+
+**参数:**
+
+- `playerID` (数字)
+
+**可取消:**否
+
+---
+
+### `onChatMessage`
+
+当玩家发送聊天消息时触发。
+
+**参数:**
+
+- `playerID` (数字)
+- `playerName` (字符串)
+- `message` (字符串)
+
+**可取消:**是——返回`1`可防止消息显示给任何人。
+
+**用法:**
+
+```lua
+function MyChatMessageHandler(sender_id, sender_name, message)
+ if message == "darn" then
+ return 1
+ else
+ return 0
+ end
+end
+
+MP.RegisterEvent("onChatMessage", "MyChatMessageHandler")
+```
+
+---
+
+### `postChatMessage`
+
+在`onChatMessage`之后触发。
+
+**参数:**
+
+- `wasSent` (布尔值)- 消息是否已发送。
+- `playerID` (数字)
+- `playerName` (字符串)
+- `message` (字符串)
+
+**可取消:**否
+
+---
+
+### `onVehicleSpawn`
+
+当玩家生成新车辆时触发。
+
+**参数:**
+
+- `playerID` (数字)
+- `vehicleID` (number)
+- `data` (字符串)- 包含车辆配置和位置数据的 JSON 字符串。
+
+**可取消:**是——返回非`0`值可阻止生成。
+
+---
+
+### `postVehicleSpawn`
+
+在`onVehicleSpawn`之后触发。
+
+**参数:**
+
+- `wasSpawned` (布尔值)- 车辆是否实际生成。
+- `playerID` (数字)
+- `vehicleID` (number)
+- `data` (字符串)
+
+**可取消:**否
+
+---
+
+### `onVehicleEdited`
+
+当玩家编辑现有车辆时触发。
+
+**参数:**
+
+- `playerID` (数字)
+- `vehicleID` (number)
+- `data` (字符串)- 新配置的 JSON 字符串(不包含位置数据)。
+
+**可取消:**是——返回非`0`值将取消编辑。
+
+---
+
+### `postVehicleEdited`
+
+在`onVehicleEdited`之后触发。
+
+**参数:**
+
+- `wasAllowed` (布尔值)- 是否允许编辑。
+- `playerID` (数字)
+- `vehicleID` (number)
+- `data` (字符串)
+
+**可取消:**否
+
+---
+
+### `onVehicleDeleted`
+
+当车辆被删除时触发。
+
+**参数:**
+
+- `playerID` (数字)
+- `vehicleID` (number)
+
+**可取消:**否
+
+---
+
+### `onVehicleReset`
+
+当玩家重置车辆时触发。
+
+**参数:**
+
+- `playerID` (数字)
+- `vehicleID` (number)
+- `data` (字符串)- 新位置和旋转的 JSON 字符串(不包含配置)。
+
+**可取消:**否
+
+---
+
+### `onVehiclePaintChanged`
+
+当车辆油漆发生变化时触发。
+
+**参数:**
+
+- `playerID` (数字)
+- `vehicleID` (number)
+- `data` (字符串)- 包含新绘制数据的 JSON 字符串。
+
+**可取消:**否
+
+---
+
+### `onFileChanged`
+
+当插件目录中的文件发生更改时触发。
+
+**参数:**
+
+- `path` (字符串)- 相对于服务器根目录的已更改文件的路径。
+
+**可取消:**否
+
+**注意:**服务器启动后添加的文件不会被跟踪。
diff --git a/docs/zh/FAQ/game-faq.md b/docs/zh/FAQ/game-faq.md
new file mode 100644
index 00000000..97a4d248
--- /dev/null
+++ b/docs/zh/FAQ/game-faq.md
@@ -0,0 +1,64 @@
+# 常见问题解答
+
+常见问题列表。
+
+---
+
+## **客户端**
+
+---
+
+### **如何安装 BeamMP?**
+
+关于如何在Windows上安装BeamMP的完整指南,您可以在[这里](https://docs.beammp.com/game/getting-started/)找到它。
+
+---
+
+### **BeamMP可以运行在盗版或者修改版的BeamNG吗?**
+
+BeamMP 无法在盗版或旧版本的 BeamNG.drive 上运行。包括但不限于第三方插件在内的修改可能会干扰 BeamMP 的正常运行(请参阅[如何清理插件](https://github.com/Protogen187/Docs/blob/main/docs/en/FAQ/Clearing-mods.md))。
BeamMP 支持团队无法针对盗版、旧版本或其他经过修改的 BeamNG.drive 所产生的问题提供技术支持。
+
+---
+
+### **BeamMP 可以在 Linux 上运行吗?**
+
+客户端在Linux上不被官方支持。但是,您可以查看我们的[指南来了解如何在Linux上使用BeamMP](../game/getting-started/#2b-linux-installation)。
+
+---
+
+### **为什么启动器被我的杀毒软件或Windows Defender标记**
+
+由于 BeamMP 需要与网络进行交互及其他因素,部分杀毒软件可能会将其标记为威胁。但请放心,所有代码中均不含任何病毒。启动器、服务器以及 Lua 客户端的源代码均可在我们的 [GitHub](https://github.com/BeamMP) 页面上找到。
+
+---
+
+### **我的游戏性能很差,我该怎么办?**
+
+我们正在努力使多人游戏体验尽可能稳定。如果您已经降低了图形设置,但性能仍然很差,请考虑在玩家较少的服务器上进行游戏。当你和很多人一起玩游戏时,游戏主要是CPU受限的,所以旧的CPU(甚至是四核)在多人的情况下会受到影响。(一般经验法则:每个CPU线程1辆车)
+
+---
+
+## **其他**
+
+---
+
+### **我在哪里可以找到代码?**
+
+所有源代码都可以在我们的[GitHub](https://github.com/BeamMP)上找到。在进行任何更改之前,请记住代码受我们的[使用条款](https://forum.beammp.com/t/terms-of-use-v1-0/43)和许可的约束:
+
+代码 | 许可证
+--- | :-:
+服务器 | [许可证](https://github.com/BeamMP/BeamMP-Server/blob/master/LICENSE)
+启动器 | [许可证](https://github.com/BeamMP/BeamMP-Launcher/blob/master/LICENSE)
+客户端 Lua | [许可证](https://github.com/BeamMP/BeamMP/blob/development/LICENSE)
+
+---
+
+### **我发现了错误或漏洞,我该怎么办?**
+
+如果问题与代码相关,并且您知道如何使用Github,请在[ Github ](https://github.com/BeamMP)上的相应存储库中打开一个新的“issue”。我们使用基于问题的工作流程,所以即使你已经修复了bug,也要考虑打开一个新的“Issue”,然后打开一个包含问题解决方案的“Pull Request”。更多关于贡献的信息可以在[中找到](https://github.com/BeamMP/BeamMP/blob/development/CONTRIBUTING.md)。
+
+如果您没有GitHub帐户,或者您不知道如何使用GitHub,或者您有任何其他问题,您可以通过以下方式与我们联系:
+
+- 如果不是敏感内容,您可以在我们的[BeamMP 论坛](https://forum.beammp.com)上创建帖子,或者您可以在我们[的官方 Discord](https://discord.gg/beammp)上报告此问题。
+- 如果信息敏感,您可以直接向我们的[Discord](https://discord.gg/beammp)上的工作人员报告问题。
diff --git a/docs/zh/FAQ/march-28-outage.md b/docs/zh/FAQ/march-28-outage.md
new file mode 100644
index 00000000..d6aecb91
--- /dev/null
+++ b/docs/zh/FAQ/march-28-outage.md
@@ -0,0 +1,25 @@
+# 2026年3月28日 BeamMP 停机故障常见问题解答(FAQ)
+
+针对 2026 年 3 月 28 日开始且目前仍在持续的BeamMP停机故障的临时常见问题解答(FAQ)。
+
+**最后更新于2026年4月1日**
+
+=== 我需要帮助!我的 BeamMP 启动器无法运行!
请尝试重新安装 BeamMP 启动器。具体操作步骤如下:
1. 访问 [beammp.com](https://beammp.com/)
2. 点击 *Download Now(立即下载)*
3. 运行安装程序并按照提示进行操作
+
+```
+!!! 注意
+
+截至 2026 年 4 月 1 日,Windows Defender SmartScreen 会将该 MSI 安装程序识别为“未知应用”。
+
+若要跳过此警告,请点击 *更多信息*,然后点击 *仍要运行*。
+```
+
+=== 我需要帮助!我的授权密钥 (authkey) 失效了!
截至 2026 年 4 月 1 日,Keymaster 和认证系统处于离线状态。这意味着您的 authkeys 将无法正常工作。若要解决此问题,请按照以下步骤操作:
1. 打开您的 ``ServerConfig.toml`` 文件,或任何存放服务器配置的地方。
2. 将 ``Private`` 设置为 ``true``。设置后应如下所示:``Private = true``。
3. 这应该能解决 authkey 的失效问题。
+
+```
+!!! 注意
+
+截至 2026 年 4 月 1 日,BeamMP 的认证系统处于离线状态。目前仅支持游客账号(Guest accounts)登录。
+
+请确保您的服务器已开启游客访问权限。
+```
diff --git a/docs/zh/beamng/cef-snippets.md b/docs/zh/beamng/cef-snippets.md
new file mode 100644
index 00000000..8dc6d15f
--- /dev/null
+++ b/docs/zh/beamng/cef-snippets.md
@@ -0,0 +1,12 @@
+!!! warning "本页面正在建设中!"
+
+```
+本站点目前正处于积极开发与维护阶段。
+
+觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
+此操作适用于站内的任何页面。
+```
+
+# BeamNG.drive CEF Code 的片段
+
+to-do
diff --git a/docs/zh/beamng/css-snippets.md b/docs/zh/beamng/css-snippets.md
new file mode 100644
index 00000000..d9d0ac06
--- /dev/null
+++ b/docs/zh/beamng/css-snippets.md
@@ -0,0 +1,189 @@
+!!! warning "本页面正在建设中!"
+
+```
+本站点目前正处于积极开发与维护阶段。
+
+觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
+此操作适用于站内的任何页面。
+```
+
+# BeamNG.drive CSS Code 的片段
+
+## 常见变量
+
+=== BeamNG Orange
+
+```
+```css
+var(--bng-orange) /*Common orange*/
+var(--bng-orange-shade1) /*70% opacity*/
+var(--bng-orange-shade2) /*40% opacity*/
+var(--bng-orange-shade1opaque)
+var(--bng-orange-shade2opaque)
+```
+```
+
+=== Monochrome
+
+```
+```css
+--- Monochrome
+var(--bng-black-8) /*80% opacity (duplicate --bng-black-o8)*/
+var(--bng-black-6) /*60% opacity (duplicate --bng-black-o6)*/
+var(--bng-black-4) /*40% opacity (duplicate --bng-black-o4)*/
+var(--bng-black-2) /*20% opacity (duplicate --bng-black-o2)*/
+
+var(--dark-neutral-grey)
+var(--neutral-grey)
+var(--light-neutral-grey)
+var(--dark-grey)
+var(--dark-grey-alpha) /*80% opacity*/
+
+var(--black-1) /*70% opacity*/
+var(--black-2) /*40% opacity (duplicate --bng-black-o4)*/
+
+var(--white-1) /*80% opacity*/
+var(--white-2) /*40% opacity*/
+var(--white-3) /*20% opacity*/
+```
+```
+
+=== BeamNG 界面颜色调色板
+
+```
+=== Orange
+
+ ```css
+ var(--bng-orange-50)
+ var(--bng-orange-100)
+ var(--bng-orange-200)
+ var(--bng-orange-300)
+ var(--bng-orange-b400)
+ var(--bng-orange-500)
+ var(--bng-orange-600)
+ var(--bng-orange-700)
+ var(--bng-orange-800)
+ var(--bng-orange-900)
+ ```
+
+=== Cool Gray
+
+ ```css
+ var(--bng-cool-gray-50)
+ var(--bng-cool-gray-100)
+ var(--bng-cool-gray-200)
+ var(--bng-cool-gray-300)
+ var(--bng-cool-gray-400)
+ var(--bng-cool-gray-500)
+ var(--bng-cool-gray-600)
+ var(--bng-cool-gray-700)
+ var(--bng-cool-gray-800)
+ var(--bng-cool-gray-900)
+ ```
+
+=== Ter Blue
+ ```css
+ var(--bng-ter-blue-50)
+ var(--bng-ter-blue-100)
+ var(--bng-ter-blue-200)
+ var(--bng-ter-blue-300)
+ var(--bng-ter-blue-400)
+ var(--bng-ter-blue-500)
+ var(--bng-ter-blue-600)
+ var(--bng-ter-blue-700)
+ var(--bng-ter-blue-800)
+ var(--bng-ter-blue-900)
+ ```
+
+=== Add Blue
+ ```css
+ var(--bng-add-blue-50)
+ var(--bng-add-blue-100)
+ var(--bng-add-blue-200)
+ var(--bng-add-blue-300)
+ var(--bng-add-blue-400)
+ var(--bng-add-blue-500)
+ var(--bng-add-blue-600)
+ var(--bng-add-blue-700)
+ var(--bng-add-blue-800)
+ var(--bng-add-blue-900)
+ ```
+
+=== Add Green
+ ```css
+ var(--bng-add-green-50)
+ var(--bng-add-green-100)
+ var(--bng-add-green-200)
+ var(--bng-add-green-300)
+ var(--bng-add-green-400)
+ var(--bng-add-green-500)
+ var(--bng-add-green-600)
+ var(--bng-add-green-700)
+ var(--bng-add-green-800)
+ var(--bng-add-green-900)
+ ```
+
+=== Add Yellow
+ ```css
+ var(--bng-add-yellow-50)
+ var(--bng-add-yellow-100)
+ var(--bng-add-yellow-200)
+ var(--bng-add-yellow-300)
+ var(--bng-add-yellow-400)
+ var(--bng-add-yellow-500)
+ var(--bng-add-yellow-600)
+ var(--bng-add-yellow-700)
+ var(--bng-add-yellow-800)
+ var(--bng-add-yellow-900)
+ ```
+
+=== Add Peach
+ ```css
+ var(--bng-add-peach-50)
+ var(--bng-add-peach-100)
+ var(--bng-add-peach-200)
+ var(--bng-add-peach-300)
+ var(--bng-add-peach-400)
+ var(--bng-add-peach-500)
+ var(--bng-add-peach-600)
+ var(--bng-add-peach-700)
+ var(--bng-add-peach-800)
+ var(--bng-add-peach-900)
+ ```
+
+=== Add Red
+ ```css
+ var(--bng-add-red-50)
+ var(--bng-add-red-100)
+ var(--bng-add-red-200)
+ var(--bng-add-red-300)
+ var(--bng-add-red-400)
+ var(--bng-add-red-500)
+ var(--bng-add-red-600)
+ var(--bng-add-red-700)
+ var(--bng-add-red-800)
+ var(--bng-add-red-900)
+ ```
+```
+
+=== 额外颜色预设
+
+```
+```css
+var(--bng-filter-orange) /*Filter preset to force SVGs to use bng-orange*/
+var(--bng-black-o8) /*80% opacity*/
+var(--bng-black-o6) /*60% opacity*/
+var(--bng-black-o4) /*40% opacity*/
+var(--bng-black-o2) /*20% opacity*/
+```
+```
+
+=== 圆角预设
+
+```
+```css
+var(--bng-corners-1) /*0.25rem*/
+var(--bng-corners-2) /*0.50rem*/
+var(--bng-corners-3) /*1.00rem*/
+```
+```
diff --git a/docs/zh/beamng/dev/modding/imgui-window-tutorial.md b/docs/zh/beamng/dev/modding/imgui-window-tutorial.md
new file mode 100644
index 00000000..3c247fd1
--- /dev/null
+++ b/docs/zh/beamng/dev/modding/imgui-window-tutorial.md
@@ -0,0 +1,88 @@
+!!! warning "本页面正在建设中!"
+
+```
+本站点目前正处于积极开发与维护阶段。
+
+觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
+此操作适用于站内的任何页面。
+
+#创建 ImGui 窗口
+```
+
+本页将介绍如何创建一个基础的 ImGui 窗口。
+
+## 设置
+
+在开始使用 ImGui 之前,需要进行一些基础设置:
+
+```lua
+local im = ui_imgui -- 缩写以避免频繁查找。这有助于性能优化
+local imguiExampleWindowOpen = im.BoolPtr(true)
+```
+
+`imguiExampleWindowOpen` 将用于决定该示例窗口是否应当进行渲染。
+
+## 窗口渲染
+
+ImGui 窗口及其内容必须在每一个需要显示的帧中重新创建。这意味着,若要使用 ImGui,必须通过某种形式的onUpdate函数来实现。
+
+```lua
+local function onUpdate()
+ if worldReadyState == 2 then
+ if imguiExampleWindowOpen[0] == true then
+ imguiExample()
+ end
+ end
+end
+M.onUpdate = onUpdate
+```
+
+只要关卡已完全加载,且示例窗口处于应当显示的状态,这段代码就会运行一个函数来创建该示例窗口。
+
+## 窗口内容
+
+如果您是初次编写 ImGui,可以把ImGui看作 HTML 的亲戚:
+
+- `im.SetNextWindowSize(im.ImVec2(x, y), im.Cond_FirstUseEver)` 用于在尚未定义视口尺寸的情况下,对其进行初始化定义。
+- `im.Begin()` 和 `im.End()`相当于你的 `
标签 + im.SameLine() -- 与 HTML 不同,这会将下一个元素附加到上一个元素的同一行 + if im.Button("The Hello World Button") then -- 类似于