first commit
161
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/10-支持基岩版客户端的Java版网络游戏概述.md
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 60分钟
|
||||
---
|
||||
|
||||
# 支持基岩版客户端的Java版网络游戏概述
|
||||
|
||||
## 目的
|
||||
|
||||
- 本文档旨在阐述通过Apollo工具,搭建并部署Java版网络游戏的流程
|
||||
|
||||
- 玩家能够通过基岩版手机客户端进入Java版网络游戏中进行游玩
|
||||
|
||||
- 开发者可以使用基岩版已有的模组SDK和附加包Json制作客户端的玩法逻辑和表现,需要的技术与中国版基岩版组件开发相似。部分功能可能无法生效
|
||||
|
||||
## 前置知识
|
||||
|
||||
### 名词介绍
|
||||
- Spigot、Spigot服
|
||||
|
||||
> Spigot是一个开源的、高效的Java版MC服务器,并且提供了丰富的api可以编写插件。他是由第三方提供的,并非官方提供,是由官方的minecraft server反编译后,打进去一些patch后而来
|
||||
|
||||
- BC、BungeeCord、BC服
|
||||
|
||||
> BungeeCord(后面简称BC)是一个代理,提供了切服、数据包转发、插件编写、BC指令等等
|
||||
|
||||
- Geyser、Geyser服、协议服
|
||||
|
||||
> Geyser是第三方开源的MC协议转换工具,它能把MC-Bedrock版本协议转换为MC-java版本协议,也就是说通过Geyser,我们能实现基岩版客户端进入Java版服务器游玩的效果
|
||||
|
||||
- Master服、Proxy服
|
||||
|
||||
> 见[名词解释](../课程2:Apollo基础知识/第2节:Apollo框架.md)
|
||||
|
||||
## 框架示例和讲解
|
||||
|
||||

|
||||
|
||||
如框架图所示,为了尽可能地兼容不同服主Spigot服框架,我们把整体的Java版网络游戏分为两部分:
|
||||
|
||||
- 负载/协议转换部分(上半部分)
|
||||
|
||||
- Java服部分(下半部分)
|
||||
|
||||
接着阐述每个部分的具体作用
|
||||
|
||||
- 负载/协议转换部分
|
||||
- 这一部分包括了Master服、Proxy服、Geyser服
|
||||
- Master和Proxy服作用和基岩版网络游戏一致
|
||||
- 由于基岩版和Java版的游戏数据协议包格式并不相同,因此,Geyser服则扮演着协议转换者的角色,它负责把基岩版的协议转换为Java版的协议
|
||||
|
||||
- Java服部分
|
||||
- 这一部分为Java游戏服,它的作用相当于基岩版网络游戏中,Lobby服和Game服的结合体,是存储玩家实际游玩数据以及世界数据的服务器
|
||||
- 它主要由两部分组成,BC服和Spigot服
|
||||
- 架构图中的DB则指额外数据库(可选)、其他则是指用于进一步管理BC、Spigot或者其他更多功能的第三方应用程序(可选)
|
||||
|
||||
为了可扩展地连接起上下两部分,框架中,我们会把Java服视为黑盒,并为BC服提供名为**BungeeMaster**的插件,这个插件安装在BC服上,负责建立起BC服和Master服的通信连接。
|
||||
|
||||
## 搭建流程
|
||||
|
||||
### 准备阶段
|
||||
|
||||
在进行Java版网络游戏搭建和部署流程前,首先需要注册成为我的世界开发者,并完成入驻申请,申请开发阶段服务器。具体步骤,请详细阅读如下文档:
|
||||
|
||||
1. [开发准备阶段概述](../课程1:成为Apollo服主及相关准备/第2节:开发准备阶段概述.md)
|
||||
|
||||
2. [入驻申请](../课程1:成为Apollo服主及相关准备/第3节:入驻申请.md)
|
||||
|
||||
3. [申请开发阶段服务器](../课程1:成为Apollo服主及相关准备/第4节:申请开发阶段服务器.md)
|
||||
|
||||
4. [使用数据库前端连接数据库](../课程1:成为Apollo服主及相关准备/第5节(拓展):使用数据库前端连接数据库.md)
|
||||
|
||||
5. [连接开发机](../课程1:成为Apollo服主及相关准备/第5节:连接开发机.md)
|
||||
|
||||
### 特别提示
|
||||
|
||||
1. 拿到机器后,要先访问添加白名单,之后才可以正常登入
|
||||
2. spigot机器的java环境对应的操作命令,分别是**java8**和**java18**,其中运行Spigot请使用java8(具体原因详见[常见问题合集](./90-常见问题合集.md))
|
||||
|
||||
### JAVA服部署流程
|
||||
- 在准备好开发机后,连接上开发机
|
||||
- 通过服主各自的Java服框架,部署各自的Java服(必须存在BC服)
|
||||
- 经过初步的调研,确定目前使用的Spigot版本为1.12.2,因此为了兼容基岩版1.18客户端,需要在**Spigot服**使用**ViaVersion**插件
|
||||
- 下载[**ViaVersion插件**](https://www.spigotmc.org/resources/viaversion.19254/),并放置于 **Spigot服目录/plugins/** 目录下。
|
||||
- 下载[**BungeeMaster插件**](./99-下载内容.md#bungeemaster插件),并放置于 **BC服目录/plugins/** 目录下。
|
||||
- 在 **BC服目录/plugins/** 下,新建文件夹 **BungeeMaster**,并在 **BungeeMaster** 文件夹下新建文件 **config.yml**(此为BungeeMaster插件配置)
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
- 然后填入如下内容,其中
|
||||
- server_id 取值区间在[12000, 14000)内,并且保持单次部署唯一即可
|
||||
|
||||
- master_port端口范围要求[29000,31000)
|
||||
|
||||
- 填写完毕后,请记下相关参数,后面需要在studio中填写
|
||||
|
||||

|
||||
|
||||
- 打开**BC服目录/config.yml**文件(此为bc服配置),查看bc服监听的端口,并记下端口参数,后面需要在studio中填写
|
||||
- 注意,此处的**query_port**和**host中冒号后面的端口值**,请保持一致
|
||||
- 该处的端口,均为**BC服**用于监听来自**Geyser**服相关连接的端口
|
||||
|
||||

|
||||
|
||||
- 配置完成后,可使用Java版客户端连接BC,测试Java服部署是否成功
|
||||
|
||||
### 负载/协议转换部分部署流程
|
||||
|
||||
- 打开MCStudio,选择基岩版服务器,并选择右上角新建选项,打开后,选择空白Spigot服
|
||||
|
||||

|
||||
|
||||
- 选择更多后,点击服务器配置,开始配置
|
||||
|
||||

|
||||
|
||||
- 其中,控制服、代理服、协议服的配置不再赘述,和基岩版网络服务器相似
|
||||
|
||||

|
||||
|
||||
- BC服的配置则根据Java服部署中,BC服的数量和配置来决定。如,根据上个步骤截图数据,则最终配置为:
|
||||
|
||||

|
||||
|
||||
- 配置完成后,点击部署
|
||||
|
||||
- 查看日志,若部署成功,则可以通过工具箱打开ModPC开发包,进入游戏开始测试
|
||||
|
||||

|
||||
|
||||
## 常见部署问题合集
|
||||
|
||||
[常见部署问题合集](./90-常见问题合集.md)
|
||||
|
||||
## 常见问题
|
||||
|
||||
Q:如何申请使用Spigot开服
|
||||
A:在开发者平台提交入驻申请,选择作品管理-上架与资源管理-网络游戏-基岩版开服工具游戏-入驻申请,使用框架勾选spigot,认真填写入驻申请。
|
||||
|
||||
Q:服务端可以使用Spigot插件么?
|
||||
A:理论上可以使用来自Spigot插件市场的插件,目前已有一批广泛使用的插件经过了测试。
|
||||
|
||||
Q:我什么时候可以上架使用Spigot的基岩版服务器?
|
||||
A:目前暂时无法上架此类游戏,您可以先进行服务器的开发,我们会在近期支持上架操作。
|
||||
|
||||
Q:我需要使用哪个版本的Spigot?是否支持Paper-Spigot?
|
||||
A:使用的是1.12版本的Spigot;暂时不支持Paper,未来会考虑支持。
|
||||
|
||||
Q:是否支持手机和电脑同服?
|
||||
A:目前仅支持手机端,如果您需要双端同服,可以选择使用Apollo进行开服。
|
||||
|
||||
Q:使用的客户端是什么?支持forge么?
|
||||
A:使用的客户端是中国版的《我的世界》基岩版,目前是1.18;很遗憾,基岩版客户端不支持forge,推荐使用官方推出的模组SDK替代。
|
||||
|
||||
Q:我是否可以将Spigot PC服移植到PE?
|
||||
A:可以,我们欢迎您这么做。但是对于客户端逻辑来说,您需要重写逻辑。
|
||||
67
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/11-Spigot服务器开发规范.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 60分钟
|
||||
---
|
||||
|
||||
# Spigot服务器开发规范
|
||||
|
||||
## Spigot服部署规范
|
||||
|
||||
- **<span style="font-size: 25px; color: red;">仅支持spigot官方BuildTools编译出的1.12.2版本,不可以使用魔改过的spigot</span>**
|
||||
- [官方BuildTools wiki](https://www.spigotmc.org/wiki/buildtools/)
|
||||
|
||||
|
||||
|
||||
## Spigot服 server.properties参数规范
|
||||
|
||||
- view-distance
|
||||
```
|
||||
建议值: 4-6
|
||||
```
|
||||
决定服务端发送的区块信息数据,对服务器性能与流量消耗影响巨大,建议调小。
|
||||
|
||||
- online-mode
|
||||
```
|
||||
必须值: false
|
||||
```
|
||||
|
||||
决定Spigot服是否进行正版验证。在Apollo中登录认证由proxy处理,spigot不需要再次验证。
|
||||
|
||||
- allow-flight
|
||||
```
|
||||
必须值: true
|
||||
```
|
||||
决定Spigot是否进行飞行检测。由于目前基岩版登录Java服务器需要经过Geyser服翻译协议,在这过程中,玩家移动相关包体不能完美翻译,若这个字段设为false,存在玩家移动被服务器当作飞行封禁的可能性。
|
||||
|
||||
- network-compression-threshold
|
||||
|
||||
```
|
||||
必须值:-1
|
||||
```
|
||||
|
||||
决定spigot与bc通信协议的压缩等级。因为spigot与bc在同一个内网,流量不需要成本,因此不压缩网络协议节省性能
|
||||
|
||||
|
||||
|
||||
## BungeeCord服 config.yml参数规范
|
||||
- connection_throttle_limit
|
||||
```
|
||||
建议值: 100
|
||||
```
|
||||
BC服允许来自同一个ip同时登录的玩家数。因为apollo中玩家登录都来自协议服,所以需要调大这个值。
|
||||
|
||||
- online-mode
|
||||
```
|
||||
必须值: false
|
||||
```
|
||||
|
||||
决定BC服是否进行正版验证,在Apollo中登录认证由proxy处理,bc不需要再次验证。
|
||||
|
||||
- network_compression_threshold
|
||||
|
||||
```
|
||||
必须值:-1
|
||||
```
|
||||
|
||||
决定bc与协议服通信协议的压缩等级。因为bc与协议服在同一个内网,流量不需要成本,因此不压缩网络协议节省性能
|
||||
120
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/20-Spigot服务器Mod简介.md
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 60分钟
|
||||
---
|
||||
|
||||
# Spigot服务器Mod简介
|
||||
|
||||
## 名词释义
|
||||
|
||||
- **SpigotMaster插件**
|
||||
为实现Spigot服务端和客户端进行自定义事件通信实现的Spigot服务器收发信息的官方插件
|
||||
|
||||
- **客户端Mod**
|
||||
客户端通过**ModSdk**接口实现的,仅包含客户端逻辑的自定义模组
|
||||
|
||||
- **Spigot插件**
|
||||
服主基于**SpigotMaster插件**、Spigot原生插件接口实现的Spigot插件
|
||||
[Spigot原生插件开发文档](https://www.spigotmc.org/wiki/spigot-plugin-development/)
|
||||
|
||||
- **游戏服Mod**
|
||||
指服主实现的玩法mod,它一般包括**客户端Mod**和**Spigot插件**
|
||||
|
||||
## 游戏服Mod的组成结构
|
||||
目前Spigot的Mod主要由两部分组成:
|
||||
|
||||
- Spigot插件:服主自行实现逻辑并修改Spigot配置,加载对应的插件,用以实现服务端相关逻辑
|
||||
|
||||
- 客户端Mod:通过目前提供的ModSdk客户端接口,编写客户端相关逻辑,用以实现客户端相关逻辑,主要包含:
|
||||
- behavior_packs用来控制客户端行为逻辑
|
||||
- resource_packs存放客户端资源
|
||||
|
||||
## 客户端Mod的目录结构样例
|
||||
|
||||
我们以demoMod为示例介绍游戏服Mod目录结构:
|
||||
|
||||
demoMod
|
||||
behavior_packs
|
||||
behavior_pack_geyser_demo_mod
|
||||
geyserDemoMod
|
||||
geyserDemoModScript
|
||||
modClient
|
||||
modCommon
|
||||
modMain.py
|
||||
__init__.py
|
||||
entities
|
||||
pack_manifest.json
|
||||
resource_packs
|
||||
resource_pack_geyser_demo_mod
|
||||
pack_manifest.json
|
||||
|
||||
| 文件/文件夹 | 解释 |
|
||||
| ------------------------- | ------------------------------------------------------------ |
|
||||
| demoMod | 游戏服Mod根目录 |
|
||||
| behavior_packs | 存放客户端行为包,可以包含多个行为包 |
|
||||
| behavior_pack_geyser_demo_mod | 行为包 |
|
||||
| geyserDemoMod | python脚本的根目录,该目录的脚本会被加到python运行环境下,可以从该路径开始import脚本文件,例如from geyserDemoMod import modMain |
|
||||
| modClient | pytho客户端行为逻辑,包含GeyserDemoModClientSystem|
|
||||
| modCommon | 通用数据,包含Modname、自定义事件等定义 |
|
||||
| resource_packs | 存放客户端资源,可以包含多个资源包 |
|
||||
| resource_pack_geyser_demo_mod | 资源包 |
|
||||
| pack_manifest.json | mod资源版本信息 |
|
||||
|
||||
更多模组SDK内容详见:
|
||||
<a href="../../20-玩法开发/13-模组SDK编程/2-Python脚本开发/0-脚本开发入门.html#modmain-py是什么" target="_blank">mod开发简介</a>
|
||||
|
||||
|
||||
### Spigot插件目录结构样例
|
||||
|
||||

|
||||
|
||||
listen_plugin
|
||||
main
|
||||
java\com\netease
|
||||
command
|
||||
ServerCommand.java
|
||||
ToClientCommand.java
|
||||
App.java
|
||||
ClientListener.java
|
||||
GlobalVar.java
|
||||
ServerOriginalListen.java
|
||||
resouces
|
||||
plugin.yml
|
||||
|
||||
| 文件/文件夹 | 解释 |
|
||||
| ------------------------- | ------------------------------------------------------------ |
|
||||
| java\com\netease | 插件逻辑代码目录 |
|
||||
| command | 指令处理类目录 |
|
||||
| App.java | 插件入口 |
|
||||
| ClientListener.java | 客户端事件监听处理函数 |
|
||||
| GlobalVar | 通用数据储存类 |
|
||||
| ServerOriginalListen | Spigot原生事件监听处理函数 |
|
||||
| resouces | 插件资源版本信息 |
|
||||
| plugin.yml | mod资源版本信息 |
|
||||
|
||||
|
||||
## 客户端Mod上传加载流程
|
||||
- 如图所示
|
||||
- mod目录结构
|
||||

|
||||
- studio配置
|
||||

|
||||
|
||||
|
||||
- Geyser读取客户端Mod后,会有如下输出
|
||||

|
||||
|
||||
## Spigot插件加载流程
|
||||
- 如图所示,把mvn clean install编译出的xxx.jar放入Spigot的Plugin文件夹
|
||||

|
||||
|
||||
- Spigot加载插件后,会有输出,具体命名由plugin.yml决定
|
||||

|
||||
|
||||
## DemoMod样例详细刨析
|
||||
|
||||
- 游戏服Mod相关的开发和样例请参见如下示例:
|
||||
|
||||
[游戏服Mod详解](./21-Spigot服与客户端python通信.md)
|
||||
|
||||
191
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/21-Spigot服与客户端python通信.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# Spigot服与客户端python通信
|
||||
|
||||
## 使用方法
|
||||
|
||||
1. spigot服需要安装SpigotMaster插件,插件api文档见[SpigotMasterAPI文档](./81-SpigotMasterAPI文档.html)
|
||||
|
||||
2. 客户端到spigot
|
||||
|
||||
- 在spigot使用spigotMaster.listenForEvent监听事件。
|
||||
|
||||
- 在客户端使用<a href="../../../mcdocs/1-ModAPI/接口/通用/事件.html#notifytoserver" rel="noopenner">NotifyToServer</a>发送事件
|
||||
|
||||
3. spigot到客户端
|
||||
|
||||
- 在客户端使用<a href="../../../mcdocs/1-ModAPI/接口/通用/事件.html#listenforevent" rel="noopenner">ListenForEvent</a>监听事件
|
||||
|
||||
- 在spigot使用spigotMaster.notifyToClient或其他多播接口发送事件
|
||||
|
||||
示例:
|
||||
|
||||
- spigot侧
|
||||
|
||||
```java
|
||||
public void onEnable() {
|
||||
SpigotMaster spigotMaster = (SpigotMaster) Bukkit.getPluginManager().getPlugin("SpigotMaster");
|
||||
if (spigotMaster != null){
|
||||
// 监听事件,然后原封不动发回去
|
||||
spigotMaster.listenForEvent("MyMod", "MySystemClient", "clientEvent", new PyRpcHandler() {
|
||||
@Override
|
||||
public void onEvent(Player player, Map<String, Object> map) {
|
||||
spigotMaster.notifyToClient(player, "MyMod", "MySystemServer", "serverEvent", map);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- python侧
|
||||
|
||||
```python
|
||||
# modMain.py
|
||||
@Mod.InitClient()
|
||||
def InitClient(self):
|
||||
clientApi.RegisterSystem("MyMod", "MySystemClient", client_system_class_path)
|
||||
|
||||
# clientSystem
|
||||
class MySystemClient(ClientSystem):
|
||||
def __init__(self, namespace, systemName):
|
||||
ClientSystem.__init__(self, namespace, systemName)
|
||||
# 注册事件,在回调函数中打印参数
|
||||
self.ListenForEvent("MyMod", "MySystemServer", "serverEvent", self, self.onEvent)
|
||||
# 给spigot发一个事件
|
||||
self.NotifyToServer("clientEvent", {'a': 1})
|
||||
|
||||
def onEvent(self, data):
|
||||
# 可以在客户端日志中看到onEvent {"a": 1}
|
||||
print 'onEvent', data
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 事件支持的参数类型及映射关系
|
||||
|
||||
### Java发送给Python
|
||||
|
||||
| Java类型 | Python类型 |
|
||||
| ------------------------ | ---------- |
|
||||
| null | None |
|
||||
| boolean | bool |
|
||||
| int | int |
|
||||
| long | long |
|
||||
| BigInteger(2^63到2^64-1) | long |
|
||||
| float | float |
|
||||
| double | float |
|
||||
| String | str |
|
||||
| List\<Object\> | list |
|
||||
| Map<String, Object> | dict |
|
||||
|
||||
### Python发送给Java
|
||||
|
||||
| Python类型 | Java类型 |
|
||||
| ---------------------------------------- | ---------- |
|
||||
| None | null |
|
||||
| bool | Boolean |
|
||||
| int/long(-2^31到2^31-1) | Integer |
|
||||
| int/long(-2^63到-2^31-1,2^31到2^63-1) | Long |
|
||||
| int/long(2^63到2^64-1) | BigInteger |
|
||||
| float | Double |
|
||||
| str | String |
|
||||
| list | List\<Object\> |
|
||||
| dict(key必须为str) | Map<String, Object> |
|
||||
|
||||
|
||||
|
||||
## 关于entityId的注意事项
|
||||
|
||||
- 客户端侧的**非玩家实体**的entityId与spigot侧org.bukkit.entity.Entity.getEntityId()获取的实体id相同
|
||||
|
||||
- 请注意spigot获取的实体id类型为**int**,而客户端modsdk接口需要的实体id类型为**str**
|
||||
|
||||
- 但客户端侧会存在一些负数的实体id,会geyser做协议转换时生成的虚拟实体,在spigot侧没有对应的实体
|
||||
|
||||
- 在**每个客户端**视角来看,**本地玩家的entityId永远为-2**,其他玩家的entityId与spigot侧getEntityId相同,也就是说:
|
||||
|
||||
- 客户端使用GetLocalPlayerId永远返回-2。如果将他发给spigot,那spigot是不能直接根据这个id获取到玩家的,需要做一些特殊处理
|
||||
|
||||
```java
|
||||
spigotMaster.listenForEvent("MyMod", "MySystemClient", "clientEvent", new PyRpcHandler() {
|
||||
@Override
|
||||
public void onEvent(Player player, Map<String, Object> map) {
|
||||
Player eventPlayer;
|
||||
String entityId = (String) map.get("entityId");
|
||||
if (entityId.equals("-2")) {
|
||||
eventPlayer = player;
|
||||
}
|
||||
else {
|
||||
// 将entityId转成int然后去获取对应player
|
||||
}
|
||||
// 处理eventPlayer的逻辑
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
- 如果在spigot侧使用getEntityId的返回值发给该玩家,那玩家客户端无法根据这个id获取到本地玩家,需要做一些特殊处理
|
||||
|
||||
```java
|
||||
int entityId;
|
||||
if (sendPlayer == player) {
|
||||
entityId = -2;
|
||||
}
|
||||
else {
|
||||
entityId = player.getEntityId()
|
||||
}
|
||||
map.put("entityId", entityId)
|
||||
spigotMaster.notifyToClient(sendPlayer, "MyMod", "MySystemServer", "serverEvent", map);
|
||||
```
|
||||
|
||||
|
||||
|
||||
## DEMO详解
|
||||
|
||||
[示例Demo](./99-下载内容.html#示例demo)中的PyRpcDemo包含了客户端mod及spigot插件。
|
||||
|
||||
进入游戏后会在右侧显示3个按钮
|
||||
|
||||
* 点击“打开窗口”会弹出一个UI,再点击“获取随机数”会从spigot获取一个0-9的随机数并显示在ui上。点击x关闭
|
||||
* 点击“绑定特效”会通知当前world内所有玩家,给发起玩家替换模型并挂接一个特效
|
||||
|
||||
* 点击”广播消息“会在spigot内所有玩家的聊天栏显示一条消息
|
||||
|
||||
|
||||
|
||||
### 客户端部分
|
||||
|
||||
1. 在客户端初始化时注册UiInitFinished事件,并在UiInitFinished事件中创建三个按钮的ui,注册后续将要使用的弹出窗口ui
|
||||
|
||||
注册两个自定义事件:
|
||||
|
||||
- bindEffect:给entityId参数对应实体更换模型以及创建特效
|
||||
- showMsg:在本地显示聊天栏消息
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
2. 在为三个按钮注册回调函数
|
||||
|
||||
”打开窗口“按钮抬起时弹出随机数的ui
|
||||
|
||||
”绑定特效“和”广播消息“按钮抬起时给spigot发送自定义消息
|
||||
|
||||

|
||||
|
||||
3. 在随机数的ui创建时监听获取随机数的回调事件,将参数中的值显示到label控件上
|
||||
|
||||
注册按钮回调:”获取随机数“按钮抬起时向spigot发送一个自定义消息,关闭按钮抬起时弹出界面
|
||||
|
||||
界面销毁时反监听获取随机数的回调事件
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### spigot部分
|
||||
|
||||
- 初始化时注册自定义事件,分别为:
|
||||
- requestRandom:给玩家返回随机数获取回调
|
||||
- requestBindEffect:给本人返回-2的entityId,给world内其他人返回spigot的entityId
|
||||
- requestMsg:给spigot内所有人返回消息
|
||||
|
||||

|
||||
186
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/22-Spigot服自定义物品.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 60分钟
|
||||
---
|
||||
|
||||
# Spigot自定义物品
|
||||
|
||||
## 使用方法
|
||||
|
||||
1. spigot服需要安装SpigotMaster插件,插件api文档见[SpigotMasterAPI文档](./81-SpigotMasterAPI文档.html)
|
||||
|
||||
2. 客户端Mod编写json、python逻辑,详见[自定义物品](../../20-玩法开发/15-自定义游戏内容/1-自定义物品/1-自定义基础物品.html)
|
||||
|
||||
3. spigot构造物品、发放给玩家,并编写物品具体使用逻辑
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 目前版本中的自定义物品,在Java服务端实际上是木剑的换皮物品,基岩客户端通过物品不同的命名空间,显示不同的贴图icon
|
||||
|
||||
- 目前的局限性:
|
||||
- 由于目前Mod由Geyser进行分发、预加载,因此通过相同Geyser连接的玩家加载的Mod都相同,加载到的自定义物品也相同
|
||||
- 由于配置中的**Components**有一部分为双端逻辑,因此此类**Components**的逻辑需要由Spigot插件实现,直接在Json中配置无法生效或效果异常。目前已知<font color="red" size=4>不可用</font>**Components**如下:
|
||||
- 基岩版自定义物品中用于物品防火的组件
|
||||
```
|
||||
设置物品是否防火
|
||||
"netease:fire_resistant"{ "value" : true}
|
||||
```
|
||||
- 基岩版自定义物品中用于物品是否可做燃料的组件
|
||||
```
|
||||
设置物品是否可作为燃料
|
||||
"netease:fuel" { "value" : true}
|
||||
```
|
||||
- 基岩版自定义物品中用于物品的使用间隔
|
||||
```
|
||||
设置物品使用间隔
|
||||
"netease:cooldown" : { "duration" : 5}
|
||||
```
|
||||
- 基岩版自定义物品中用于物品武器属性的组件
|
||||
- 当**type**值为sword时,能达到客户端玩家模型手持物品的效果
|
||||
- 其他**type**类型以及字段暂时不可用
|
||||
```
|
||||
设置物品作为物品时的各类属性
|
||||
"netease:weapon" : { "type" : "pickaxe", "level" : 3}
|
||||
```
|
||||
- 由于目前物品在Spigot服中实际上为木剑换皮,下述组件为固定值
|
||||
```
|
||||
**"minecraft:max_damage" : 59**
|
||||
```
|
||||
- 当使用这个组件时,客户端可显示出自定义物品耐久条
|
||||
- 当值为**非59**时,会导致客户端物品耐久异常
|
||||
- 当值为 **59**时,客户端耐久条会随服务端设置的物品耐久变化而变化
|
||||
- 当不使用这个组件时,客户端不显示出自定义物品耐久条
|
||||
|
||||
## Demo详解
|
||||
|
||||
Demo实现了三个不同的自定义物品:
|
||||
- 爆炸头盔
|
||||
当鼠标右键方块时,方块所在位置发生半径为1.5格的爆炸
|
||||
- Amiibo之剑
|
||||
当鼠标右键方块时,方块所在位置出现落雷效果,并随机生成物品,必定掉落**落雷剑**
|
||||
- 落雷剑
|
||||
当鼠标右键方块时,方块所在位置生成落雷,效果和打雷效果一致,对附近生物造成伤害
|
||||
|
||||
### 开发流程
|
||||
|
||||
#### 客户端Mod编写
|
||||
##### 目的
|
||||
为了让Geyser能加载新增的自定义物品,我们需要编写客户端Mod
|
||||
##### 流程
|
||||
|
||||
- 在behavior文件夹中新建**netease_item_beh**目录,如下图所示
|
||||
|
||||

|
||||
|
||||
- 在**netease_item_beh**目录下新增三个物品Json,样例如下:
|
||||
|
||||

|
||||
|
||||
- 在**resource**文件夹中新建**netease_item_res**、**texts**、**textures**目录,如下图所示
|
||||
这三个目录的作用分别如下:
|
||||
- **netease_item_res**用于存放自定义物品客户端贴图表现Json
|
||||
- **texts**用于存放自定义内容的中文命名
|
||||
- **textures**用于存放自定义内容的贴图文件
|
||||
|
||||

|
||||
|
||||
|
||||
- 在**netease_item_res**目录下新增三个物品Json,样例如下:
|
||||
样例中,我们通过**minecraft:icon**这个**Component**为物品设置贴图
|
||||
|
||||

|
||||
|
||||
- 在**texts**目录下新增**zh_CN.lang**文件,设置自定义物品的名称,样例如下:
|
||||
|
||||

|
||||
|
||||
- 在**textures**目录下新增**item_texture.json**文件,设置物品贴图对应的贴图路径,样例如下:
|
||||
|
||||

|
||||

|
||||
|
||||
- 至此,客户端Mod中自定义物品完成
|
||||
|
||||
#### Spigot插件编写
|
||||
|
||||
##### 目的
|
||||
为了让自定义物品能有不同的效果、功能,我们还需要编写Spigot插件,实现不同物品的不同效果逻辑
|
||||
##### 流程
|
||||
|
||||
- 插件编写
|
||||
|
||||
1. 在plugin.yml中添加依赖
|
||||
|
||||
```yml
|
||||
depend:
|
||||
- SpigotMaster
|
||||
```
|
||||
|
||||
2. 如App.java所示,实例ServerOriginalListener监听了Spigot原生事件
|
||||
|
||||
通过下述接口实现
|
||||
```
|
||||
getServer().getPluginManager().registerEvents(new ServerOriginalListener(), this);
|
||||
```
|
||||
|
||||
3. 实例**ServerOriginalListener**监听了Spigot原生的事件,**ServerOriginalListener**监听方法如图:
|
||||
示例中,**ServerOriginalListener**一共监听了两个事件,如下:
|
||||
- 玩家加入事件(PlayerJoinEvent), 效果为玩家加入游戏时,给玩家自动发放两个物品
|
||||
- 玩家交互事件(PlayerInteractEvent),效果为玩家和方块右键交互时,根据不同自定义物品,触发不同的效果
|
||||

|
||||
|
||||
4. 创建物品
|
||||
- 通过Spigot提供的Api,创建物品ItemStack
|
||||
```
|
||||
@Param material 物品material(自定义物品的material通过下一步获取)
|
||||
@Param amount 物品数量
|
||||
ItemStack customItem1 = new ItemStack(material, amount);
|
||||
```
|
||||
- 在创建ItemStack时,通过下述接口获取自定义物品中的Material
|
||||
```
|
||||
@Param itemIdentifier 自定义物品Identifier,需要和客户端Mod中定义一致
|
||||
@Return Material 自定义物品在Spigot中对应的Material
|
||||
SpigotMaster.getCustomItemMaterial(itemIdentifier)
|
||||
```
|
||||
- 同时,通过下述接口,为物品设置基岩版中对应的Identifier
|
||||
**PS: 这一步为必须步骤,缺少这一步时,会导致客户端无法正常生成自定义物品**
|
||||
```
|
||||
@Param itemStack 通过Spigot接口生成的ItemStack
|
||||
@Param itemIdentifier 自定义物品Identifier,需要和客户端Mod中定义一致
|
||||
SpigotMaster.setCustomItemIdentifier(itemStack, itenIdentifier)
|
||||
```
|
||||
- 根据需要,再进一步修改ItemStack的其他属性,如样例中的lore
|
||||
|
||||
5. 使用物品
|
||||
- 通过事件参数获取ItemStack:
|
||||
```
|
||||
ItemStack item = event.getItem();
|
||||
```
|
||||
- 通过接口获取物品的Material:
|
||||
```
|
||||
@Param itemIdentifier 自定义物品Identifier,需要和客户端Mod中定义一致
|
||||
@Return Material 自定义物品在Spigot中对应的Material
|
||||
SpigotMaster.getCustomItemMaterial(itemIdentifier)
|
||||
```
|
||||
- 当事件物品的Material和自定义物品的Material一致时,判定为使用自定义物品,具体物品效果、逻辑还需进一步区分
|
||||
|
||||
- 通过接口获取物品的Identifier:
|
||||
```
|
||||
@Param itemStack 通过Spigot接口生成的ItemStack
|
||||
@Return String itemIdentifier,非自定义物品返回null
|
||||
SpigotMaster.getCustomItemIdentifier(itemStack)
|
||||
```
|
||||
根据获取到的Identifier实现不同的逻辑,如图所示
|
||||

|
||||
|
||||
6.运行mvn clean install,会在插件target下生成插件.jar,把生成的jar放置于Spigot服的plugin文件夹下
|
||||
|
||||
7.最终实现的效果如下:
|
||||
- 玩家进入游戏即可获取两个自定义物品
|
||||

|
||||
|
||||
- 使用自定义物品1时发生爆炸
|
||||
- 使用自定义物品2时有打雷效果,并生成物品,其中物品必掉落自定义物品3
|
||||
- 使用自定义物品3时生成闪电
|
||||
|
||||
205
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/22-Spigot游戏服自定义物品Demo详解.md
Normal file
@@ -0,0 +1,205 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 60分钟
|
||||
---
|
||||
|
||||
# Spigot自定义物品Demo详解
|
||||
|
||||
## 前情提要
|
||||
|
||||
[Spigot服务器Mod简介](./20-Spigot服务器Mod简介.md)
|
||||
|
||||
## 简要原理
|
||||
|
||||
- 客户端Mod实现流程可以参照以下文档:
|
||||
[自定义物品](../../20-玩法开发/15-自定义游戏内容/1-自定义物品/1-自定义基础物品.md)
|
||||
- 目前版本中的自定义物品,在Java服务端实际上是木剑的换皮物品,基岩客户端通过物品不同的命名空间,显示不同的贴图icon
|
||||
|
||||
### Demo效果
|
||||
|
||||
Demo实现了三个不同的自定义物品:
|
||||
- 爆炸头盔
|
||||
当鼠标右键方块时,方块所在位置发生半径为1.5格的爆炸
|
||||
- Amiibo之剑
|
||||
当鼠标右键方块时,方块所在位置出现落雷效果,并随机生成物品,必定掉落**落雷剑**
|
||||
- 落雷剑
|
||||
当鼠标右键方块时,方块所在位置生成落雷,效果和打雷效果一致,对附近生物造成伤害
|
||||
|
||||
### 开发流程
|
||||
|
||||
#### 客户端Mod编写
|
||||
##### 目的
|
||||
为了让Geyser能加载新增的自定义物品,我们需要编写客户端Mod
|
||||
##### 流程
|
||||
|
||||
- 在behavior文件夹中新建**netease_item_beh**目录,如下图所示
|
||||

|
||||
|
||||
- 在**netease_item_beh**目录下新增三个物品Json,样例如下:
|
||||

|
||||
|
||||
- 在**resource**文件夹中新建**netease_item_res**、**texts**、**textures**目录,如下图所示
|
||||

|
||||
这三个目录的作用分别如下:
|
||||
- **netease_item_res**用于存放自定义物品客户端贴图表现Json
|
||||
- **texts**用于存放自定义内容的中文命名
|
||||
- **textures**用于存放自定义内容的贴图文件
|
||||
|
||||
- 在**netease_item_res**目录下新增三个物品Json,样例如下:
|
||||
样例中,我们通过**minecraft:icon**这个**Component**为物品设置贴图
|
||||

|
||||
|
||||
- 在**texts**目录下新增**zh_CN.lang**文件,设置自定义物品的名称,样例如下:
|
||||

|
||||
|
||||
- 在**textures**目录下新增**item_texture.json**文件,设置物品贴图对应的贴图路径,样例如下:
|
||||

|
||||

|
||||
|
||||
- 至此,客户端Mod中自定义物品完成
|
||||
|
||||
#### Spigot插件编写
|
||||
|
||||
##### 目的
|
||||
为了让自定义物品能有不同的效果、功能,我们还需要编写Spigot插件,实现不同物品的不同效果逻辑
|
||||
##### 流程
|
||||
|
||||
- 安装插件到本地maven
|
||||
|
||||
下载 **SpigotMaster** 的jar包,然后执行以下指令,**path-to-jar**替换为jar路径
|
||||
|
||||
```shell
|
||||
mvn install:install-file -Dfile=path-to-jar
|
||||
-DgroupId=com.neteasemc
|
||||
-DartifactId=SpigotMaster
|
||||
-Dversion=1.0-SNAPSHOT
|
||||
-Dpackaging=jar
|
||||
```
|
||||
|
||||
- 插件编写
|
||||
|
||||
1. 在pom.xml中添加依赖
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.neteasemc</groupId>
|
||||
<artifactId>SpigotMaster</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
2. 在plugin.yml中添加依赖
|
||||
|
||||
```yml
|
||||
depend:
|
||||
- SpigotMaster
|
||||
```
|
||||
|
||||
3. 如App.java所示,实例ServerOriginalListener监听了Spigot原生事件
|
||||
|
||||
通过下述接口实现
|
||||
```
|
||||
getServer().getPluginManager().registerEvents(new ServerOriginalListener(), this);
|
||||
```
|
||||
|
||||
4. 实例**ServerOriginalListener**监听了Spigot原生的事件,**ServerOriginalListener**监听方法如图:
|
||||
示例中,**ServerOriginalListener**一共监听了两个事件,如下:
|
||||
- 玩家加入事件(PlayerJoinEvent), 效果为玩家加入游戏时,给玩家自动发放两个物品
|
||||
- 玩家交互事件(PlayerInteractEvent),效果为玩家和方块右键交互时,根据不同自定义物品,触发不同的效果
|
||||

|
||||
|
||||
5. 创建物品
|
||||
- 通过Spigot提供的Api,创建物品ItemStack
|
||||
```
|
||||
@Param material 物品material(自定义物品的material通过下一步获取)
|
||||
@Param amount 物品数量
|
||||
ItemStack customItem1 = new ItemStack(material, amount);
|
||||
```
|
||||
- 在创建ItemStack时,通过下述接口获取自定义物品中的Material
|
||||
```
|
||||
@Param itemIdentifier 自定义物品Identifier,需要和客户端Mod中定义一致
|
||||
@Return Material 自定义物品在Spigot中对应的Material
|
||||
SpigotMaster.getCustomItemMaterial(itemIdentifier)
|
||||
```
|
||||
- 同时,通过下述接口,为物品设置基岩版中对应的Identifier
|
||||
**PS: 这一步为必须步骤,缺少这一步时,会导致客户端无法正常生成自定义物品**
|
||||
```
|
||||
@Param itemStack 通过Spigot接口生成的ItemStack
|
||||
@Param itemIdentifier 自定义物品Identifier,需要和客户端Mod中定义一致
|
||||
SpigotMaster.setCustomItemIdentifier(itemStack, itenIdentifier)
|
||||
```
|
||||
- 根据需要,再进一步修改ItemStack的其他属性,如样例中的lore
|
||||
|
||||
6. 使用物品
|
||||
- 通过事件参数获取ItemStack:
|
||||
```
|
||||
ItemStack item = event.getItem();
|
||||
```
|
||||
- 通过接口获取物品的Material:
|
||||
```
|
||||
@Param itemIdentifier 自定义物品Identifier,需要和客户端Mod中定义一致
|
||||
@Return Material 自定义物品在Spigot中对应的Material
|
||||
SpigotMaster.getCustomItemMaterial(itemIdentifier)
|
||||
```
|
||||
- 当事件物品的Material和自定义物品的Material一致时,判定为使用自定义物品,具体物品效果、逻辑还需进一步区分
|
||||
|
||||
- 通过接口获取物品的Identifier:
|
||||
```
|
||||
@Param itemStack 通过Spigot接口生成的ItemStack
|
||||
@Return String itemIdentifier,非自定义物品返回null
|
||||
SpigotMaster.getCustomItemIdentifier(itemStack)
|
||||
```
|
||||
根据获取到的Identifier实现不同的逻辑,如图所示
|
||||

|
||||
|
||||
7.运行mvn clean install,会在插件target下生成插件.jar,把生成的jar放置于Spigot服的plugin文件夹下
|
||||
|
||||
8.最终实现的效果如下:
|
||||
- 玩家进入游戏即可获取两个自定义物品
|
||||

|
||||
|
||||
- 使用自定义物品1时发生爆炸
|
||||
- 使用自定义物品2时有打雷效果,并生成物品,其中物品必掉落自定义物品3
|
||||
- 使用自定义物品3时生成闪电
|
||||
|
||||
### Q&A
|
||||
|
||||
- **SpigotMaster插件**简要API文档
|
||||
|
||||
[SpigotMaster插件API文档](./80-SpigotMaster简要API文档.md)
|
||||
|
||||
|
||||
### **需要注意的是**
|
||||
- 目前的局限性:
|
||||
- 由于目前Mod由Geyser进行分发、预加载,因此通过相同Geyser连接的玩家加载的Mod都相同,加载到的自定义物品也相同
|
||||
- 由于配置中的**Components**有一部分为双端逻辑,因此此类**Components**的逻辑需要由Spigot插件实现,直接在Json中配置无法生效或效果异常。目前已知不可用**Component**如下:
|
||||
- 基岩版自定义物品中用于物品防火的组件
|
||||
```
|
||||
设置物品是否防火
|
||||
"netease:fire_resistant"{ "value" : true}
|
||||
```
|
||||
- 基岩版自定义物品中用于物品是否可做燃料的组件
|
||||
```
|
||||
设置物品是否可作为燃料
|
||||
"netease:fuel" { "value" : true}
|
||||
```
|
||||
- 基岩版自定义物品中用于物品的使用间隔
|
||||
```
|
||||
设置物品使用间隔
|
||||
"netease:cooldown" : { "duration" : 5}
|
||||
```
|
||||
- 基岩版自定义物品中用于物品武器属性的组件
|
||||
```
|
||||
设置物品作为物品时的各类属性
|
||||
"netease:weapon" : { "type" : "pickaxe", "level" : 3}
|
||||
```
|
||||
- 由于目前物品在Spigot服中实际上为木剑换皮,下述组件为固定值
|
||||
```
|
||||
**"minecraft:max_damage" : 59**
|
||||
```
|
||||
- 当使用这个组件时,客户端可显示出自定义物品耐久条
|
||||
- 当值为**非59**时,会导致客户端物品耐久异常
|
||||
- 当值为 **59**时,客户端耐久条会随服务端设置的物品耐久变化而变化
|
||||
- 当不使用这个组件时,客户端不显示出自定义物品耐久条
|
||||
100
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/80-SpigotMaster简要API文档.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# SpigotMaster简要API文档
|
||||
|
||||
- 注册与发送客户端事件
|
||||
|
||||
spigot侧:
|
||||
|
||||
- map中的值支持的数据类型:
|
||||
|
||||
| Java类型 | Python类型 |
|
||||
| ----------------------- | ----------------- |
|
||||
| null | None |
|
||||
| boolean | bool |
|
||||
| int | int |
|
||||
| long | long |
|
||||
| BigInteger(2^63~2^64-1) | long(2^63~2^64-1) |
|
||||
| float | float |
|
||||
| double | float |
|
||||
| String | str |
|
||||
| List\<Object\> | list |
|
||||
| Map<String, Object> | dict |
|
||||
|
||||
- 客户端侧的实体id与spigot侧org.bukkit.entity.Entity.getEntityId()获取的实体id相同
|
||||
|
||||
- 请注意spigot获取的实体id类型为**int**,而客户端modsdk接口需要的实体id类型为**str**
|
||||
|
||||
- 但客户端侧会存在一些负数的实体id,会geyser做协议转换时生成的虚拟实体,在spigot侧没有对应的实体
|
||||
|
||||
示例:
|
||||
|
||||
```java
|
||||
public void onEnable() {
|
||||
SpigotMaster spigotMaster = (SpigotMaster) Bukkit.getPluginManager().getPlugin("SpigotMaster");
|
||||
if (spigotMaster != null){
|
||||
spigotMaster.listenForEvent("MyMod", "MySystemClient", "clientEvent", new PyRpcHandler() {
|
||||
@Override
|
||||
public void onEvent(Player player, Map<String, Object> map) {
|
||||
spigotMaster.notifyToClient(player, "MyMod", "MySystemServer", "serverEvent", map);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
客户端侧:
|
||||
|
||||
```python
|
||||
# modMain.py
|
||||
@Mod.InitClient()
|
||||
def InitClient(self):
|
||||
clientApi.RegisterSystem("MyMod", "MySystemClient", client_system_class_path)
|
||||
|
||||
# clientSystem
|
||||
class MySystemClient(ClientSystem):
|
||||
def __init__(self, namespace, systemName):
|
||||
ClientSystem.__init__(self, namespace, systemName)
|
||||
self.ListenForEvent("MyMod", "MySystemServer", "serverEvent", self, self.onEvent)
|
||||
self.NotifyToServer("clientEvent", {'a': 1})
|
||||
|
||||
def onEvent(self, data):
|
||||
print 'onEvent', data
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
class SpigotMaster
|
||||
|
||||
- listenForEvent
|
||||
|
||||
监听客户端事件
|
||||
|
||||
- notifyToClient
|
||||
|
||||
发事件到指定player
|
||||
|
||||
- notifyToMultiClients
|
||||
|
||||
发事件到多个player
|
||||
|
||||
- notifyToClientsNearby
|
||||
|
||||
发事件到位置附近的player
|
||||
|
||||
- broadcastToAllClient
|
||||
|
||||
广播事件到server中所有player
|
||||
|
||||
- getCustomItemIdentifier(itemStack)
|
||||
获取自定义物品identifier
|
||||
@Param ItemStack itemStack spigot生成的itemStack
|
||||
@Return String customItemIdentifier 当物品为自定义物品时,返回自定义物品的identifier,其他情况返回null
|
||||
|
||||
- setCustomItemIdentifier(itemStack, customItemIdentifier)
|
||||
设置自定义物品identifier
|
||||
@Param itemStack spigot生成的itemStack
|
||||
@Param String customItemIdentifier 自定义物品的identifier
|
||||
|
||||
- getCustomItemMaterial(customItemIdentifier)
|
||||
获取自定义物品identifier
|
||||
@Param String customItemIdentifier 自定义物品的identifier
|
||||
@Return Mateiral 目前版本V1.1.0版本中,固定返回Material.WOOD_SWORD(亦即木剑换皮)
|
||||
312
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/81-SpigotMasterAPI文档.md
Normal file
@@ -0,0 +1,312 @@
|
||||
# SpigotMasterAPI文档
|
||||
|
||||
com.neteasemc.spigotmaster
|
||||
|
||||
## 类 SpigotMaster
|
||||
|
||||
- java.lang.Object
|
||||
- org.bukkit.plugin.PluginBase
|
||||
- org.bukkit.plugin.java.JavaPlugin
|
||||
- com.neteasemc.spigotmaster.SpigotMaster
|
||||
|
||||
- 所有已实现的接口:
|
||||
|
||||
org.bukkit.command.CommandExecutor, org.bukkit.command.TabCompleter, org.bukkit.command.TabExecutor, org.bukkit.plugin.Plugin
|
||||
|
||||
------
|
||||
|
||||
```
|
||||
public class SpigotMaster
|
||||
extends org.bukkit.plugin.java.JavaPlugin
|
||||
```
|
||||
|
||||
- ### 构造器概要
|
||||
|
||||
| 构造器和说明 |
|
||||
| :--------------- |
|
||||
| `SpigotMaster()` |
|
||||
|
||||
- ### 方法概要
|
||||
|
||||
| 限定符和类型 | 方法和说明 |
|
||||
| :------------------------------- | :----------------------------------------------------------- |
|
||||
| `void` | `broadcastToAllClient(org.bukkit.entity.Player except, java.lang.String namespace, java.lang.String system, java.lang.String event, java.util.Map<java.lang.String,java.lang.Object> data)`<br>给服务器内的所有玩家发送服务端事件。 |
|
||||
| `void` | `broadcastToAllClient(org.bukkit.entity.Player except, org.bukkit.World world, java.lang.String namespace, java.lang.String system, java.lang.String event, java.util.Map<java.lang.String,java.lang.Object> data)`<br/>给某个world内的所有玩家发送服务端事件。 |
|
||||
| `java.lang.String` | `getCustomItemIdentifier(org.bukkit.inventory.ItemStack spigotItemStack)`<br/>获取自定义物品名的identifier |
|
||||
| `org.bukkit.Material` | `getCustomItemMaterial(java.lang.String customItemIdentifier)`<br/>获取自定义物品名的java材质 在目前的实现中,固定是Material.WOOD_SWORD,亦即木剑换皮 |
|
||||
| `void` | `listenForEvent(java.lang.String namespace, java.lang.String system, java.lang.String event, com.neteasemc.spigotmaster.PyRpcHandler handler)`<br/>注册客户端事件 |
|
||||
| `void` | `notifyToClient(org.bukkit.entity.Player player, java.lang.String namespace, java.lang.String system, java.lang.String event, java.util.Map<java.lang.String,java.lang.Object> data)`<br/>给指定玩家发送服务端事件 |
|
||||
| `void` | `notifyToClientsNearby(org.bukkit.entity.Player except, org.bukkit.Location loc, double dist, java.lang.String namespace, java.lang.String system, java.lang.String event, java.util.Map<java.lang.String,java.lang.Object> data)`<br/>给某个位置附近一定半径内的所有玩家发送服务端事件。 |
|
||||
| `void` | `notifyToMultiClients(java.util.List<org.bukkit.entity.Player> players, java.lang.String namespace, java.lang.String system, java.lang.String event, java.util.Map<java.lang.String,java.lang.Object> data)`<br/>给多个玩家发送服务端事件。 |
|
||||
| `void` | `onDisable()` |
|
||||
| `void` | `onEnable()` |
|
||||
| `org.bukkit.inventory.ItemStack` | `setCustomItemIdentifier(org.bukkit.inventory.ItemStack spigotItemStack, java.lang.String customIdentifier)`<br/>设置自定义物品的identifier |
|
||||
|
||||
- ### 从类继承的方法 org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
```
|
||||
getCommand, getConfig, getDataFolder, getDefaultWorldGenerator, getDescription, getLogger, getPlugin, getPluginLoader, getProvidingPlugin, getResource, getServer, isEnabled, isNaggable, onCommand, onLoad, onTabComplete, reloadConfig, saveConfig, saveDefaultConfig, saveResource, setNaggable, toString
|
||||
```
|
||||
|
||||
- ### 从类继承的方法 org.bukkit.plugin.PluginBase
|
||||
|
||||
```
|
||||
equals, getName, hashCode
|
||||
```
|
||||
|
||||
- ### 从类继承的方法 java.lang.Object
|
||||
|
||||
```
|
||||
getClass, notify, notifyAll, wait, wait, wait
|
||||
```
|
||||
|
||||
- ### 构造器详细资料
|
||||
|
||||
|
||||
|
||||
- #### SpigotMaster
|
||||
|
||||
```
|
||||
public SpigotMaster()
|
||||
```
|
||||
|
||||
- ### 方法详细资料
|
||||
|
||||
|
||||
|
||||
- #### onEnable
|
||||
|
||||
```
|
||||
public void onEnable()
|
||||
```
|
||||
|
||||
- 指定者:
|
||||
|
||||
`onEnable` 在接口中 `org.bukkit.plugin.Plugin`
|
||||
|
||||
- 覆盖:
|
||||
|
||||
`onEnable` 在类中 `org.bukkit.plugin.java.JavaPlugin`
|
||||
|
||||
|
||||
|
||||
- #### onDisable
|
||||
|
||||
```
|
||||
public void onDisable()
|
||||
```
|
||||
|
||||
- 指定者:
|
||||
|
||||
`onDisable` 在接口中 `org.bukkit.plugin.Plugin`
|
||||
|
||||
- 覆盖:
|
||||
|
||||
`onDisable` 在类中 `org.bukkit.plugin.java.JavaPlugin`
|
||||
|
||||
|
||||
|
||||
- #### getCustomItemMaterial
|
||||
|
||||
```
|
||||
public org.bukkit.Material getCustomItemMaterial(java.lang.String customItemIdentifier)
|
||||
```
|
||||
|
||||
获取自定义物品名的java材质 在目前的实现中,固定是Material.WOOD_SWORD,亦即木剑换皮
|
||||
|
||||
- 参数:
|
||||
|
||||
`customItemIdentifier` - 自定义物品identifier
|
||||
|
||||
|
||||
|
||||
- #### getCustomItemIdentifier
|
||||
|
||||
```
|
||||
public java.lang.String getCustomItemIdentifier(org.bukkit.inventory.ItemStack spigotItemStack)
|
||||
```
|
||||
|
||||
获取自定义物品名的identifier
|
||||
|
||||
- 参数:
|
||||
|
||||
`spigotItemStack` - itemStack
|
||||
|
||||
|
||||
|
||||
- #### setCustomItemIdentifier
|
||||
|
||||
```
|
||||
public org.bukkit.inventory.ItemStack setCustomItemIdentifier(org.bukkit.inventory.ItemStack spigotItemStack,
|
||||
java.lang.String customIdentifier)
|
||||
```
|
||||
|
||||
设置自定义物品的identifier
|
||||
|
||||
- 参数:
|
||||
|
||||
`spigotItemStack` - itemStack
|
||||
|
||||
`customIdentifier` - 自定义物品identifier
|
||||
|
||||
|
||||
|
||||
- #### listenForEvent
|
||||
|
||||
```
|
||||
public void listenForEvent(java.lang.String namespace,
|
||||
java.lang.String system,
|
||||
java.lang.String event,
|
||||
com.neteasemc.spigotmaster.PyRpcHandler handler)
|
||||
```
|
||||
|
||||
注册客户端事件
|
||||
|
||||
- 参数:
|
||||
|
||||
`namespace` - 来源客户端系统的namespace
|
||||
|
||||
`system` - 来源客户端系统的systemName
|
||||
|
||||
`event` - 事件名
|
||||
|
||||
`handler` - 回调函数
|
||||
|
||||
|
||||
|
||||
- #### notifyToClient
|
||||
|
||||
```
|
||||
public void notifyToClient(org.bukkit.entity.Player player,
|
||||
java.lang.String namespace,
|
||||
java.lang.String system,
|
||||
java.lang.String event,
|
||||
java.util.Map<java.lang.String,java.lang.Object> data)
|
||||
```
|
||||
|
||||
给指定玩家发送服务端事件
|
||||
|
||||
- 参数:
|
||||
|
||||
`player` - 接收事件的玩家
|
||||
|
||||
`namespace` - 在客户端系统使用ListenForEvent监听的namespace
|
||||
|
||||
`system` - 在客户端系统使用ListenForEvent监听的systemName
|
||||
|
||||
`event` - 事件名
|
||||
|
||||
`data` - 事件参数。注意,要使用-2指代本地玩家的entityId。
|
||||
|
||||
|
||||
|
||||
- #### notifyToMultiClients
|
||||
|
||||
```
|
||||
public void notifyToMultiClients(java.util.List<org.bukkit.entity.Player> players,
|
||||
java.lang.String namespace,
|
||||
java.lang.String system,
|
||||
java.lang.String event,
|
||||
java.util.Map<java.lang.String,java.lang.Object> data)
|
||||
```
|
||||
|
||||
给多个玩家发送服务端事件。 因为-2的entityId对于不同玩家来说都指代本机玩家,而非某个固定的实体,所以不要在多播中发送这种信息。
|
||||
|
||||
- 参数:
|
||||
|
||||
`players` - 接收事件的玩家列表
|
||||
|
||||
`namespace` - 在客户端系统使用ListenForEvent监听的namespace
|
||||
|
||||
`system` - 在客户端系统使用ListenForEvent监听的systemName
|
||||
|
||||
`event` - 事件名
|
||||
|
||||
`data` - 事件参数
|
||||
|
||||
|
||||
|
||||
- #### notifyToClientsNearby
|
||||
|
||||
```
|
||||
public void notifyToClientsNearby(org.bukkit.entity.Player except,
|
||||
org.bukkit.Location loc,
|
||||
double dist,
|
||||
java.lang.String namespace,
|
||||
java.lang.String system,
|
||||
java.lang.String event,
|
||||
java.util.Map<java.lang.String,java.lang.Object> data)
|
||||
```
|
||||
|
||||
给某个位置附近一定半径内的所有玩家发送服务端事件。 因为-2的entityId对于不同玩家来说都指代本机玩家,而非某个固定的实体,所以不要在多播中发送这种信息。
|
||||
|
||||
- 参数:
|
||||
|
||||
`except` - 发送事件时排除掉这个玩家,可以为null表示不排除
|
||||
|
||||
`loc` - 圆心位置
|
||||
|
||||
`dist` - 半径
|
||||
|
||||
`namespace` - 在客户端系统使用ListenForEvent监听的namespace
|
||||
|
||||
`system` - 在客户端系统使用ListenForEvent监听的systemName
|
||||
|
||||
`event` - 事件名
|
||||
|
||||
`data` - 事件参数
|
||||
|
||||
|
||||
|
||||
- #### broadcastToAllClient
|
||||
|
||||
```
|
||||
public void broadcastToAllClient(org.bukkit.entity.Player except,
|
||||
org.bukkit.World world,
|
||||
java.lang.String namespace,
|
||||
java.lang.String system,
|
||||
java.lang.String event,
|
||||
java.util.Map<java.lang.String,java.lang.Object> data)
|
||||
```
|
||||
|
||||
给某个world内的所有玩家发送服务端事件。 因为-2的entityId对于不同玩家来说都指代本机玩家,而非某个固定的实体,所以不要在多播中发送这种信息。
|
||||
|
||||
- 参数:
|
||||
|
||||
`except` - 发送事件时排除掉这个玩家,可以为null表示不排除
|
||||
|
||||
`world` - 所在world
|
||||
|
||||
`namespace` - 在客户端系统使用ListenForEvent监听的namespace
|
||||
|
||||
`system` - 在客户端系统使用ListenForEvent监听的systemName
|
||||
|
||||
`event` - 事件名
|
||||
|
||||
`data` - 事件参数
|
||||
|
||||
|
||||
|
||||
- #### broadcastToAllClient
|
||||
|
||||
```
|
||||
public void broadcastToAllClient(org.bukkit.entity.Player except,
|
||||
java.lang.String namespace,
|
||||
java.lang.String system,
|
||||
java.lang.String event,
|
||||
java.util.Map<java.lang.String,java.lang.Object> data)
|
||||
```
|
||||
|
||||
给服务器内的所有玩家发送服务端事件。 因为-2的entityId对于不同玩家来说都指代本机玩家,而非某个固定的实体,所以不要在多播中发送这种信息。
|
||||
|
||||
- 参数:
|
||||
|
||||
`except` - 发送事件时排除掉这个玩家,可以为null表示不排除
|
||||
|
||||
`namespace` - 在客户端系统使用ListenForEvent监听的namespace
|
||||
|
||||
`system` - 在客户端系统使用ListenForEvent监听的systemName
|
||||
|
||||
`event` - 事件名
|
||||
|
||||
`data` - 事件参数
|
||||
44
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/90-常见问题合集.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 60分钟
|
||||
---
|
||||
|
||||
# 常见问题合集
|
||||
|
||||
- 目前Mod经过Geyser加载并分发,因此当前版本中,通过同一个Geyser连接的玩家,加载的Mod都相同,如果需要实现不同bc或者spigot加载不同的Mod效果,可通过配置不同的geyser连接不同的bc实现
|
||||
|
||||
- 由于目前Geyser和Spigot使用的java版本不同,因此开发机上存在两个版本的java,对应的命令分别是 **java18** 以及 **java8**,因此,在启动Spigot时,请使用命令**java8**
|
||||

|
||||
|
||||
- 当部署时,开启了如下标识
|
||||
|
||||

|
||||
|
||||
> 则在bc服和master未成功连接时,登录会有如下提示
|
||||
|
||||

|
||||
|
||||
> 当对应标识未开启时,提示如下:
|
||||
|
||||

|
||||
|
||||
> 当出现上述提示时,请查看BC服日志,查看BungeeMaster插件是否正常加载以及master服是否正常连接上,正常连接会有如下日志打印:
|
||||
|
||||

|
||||
|
||||
- 使用ssh登录服务器后,查看对应网络id下的geyser目录,可以查看geyser的日志
|
||||
|
||||

|
||||
|
||||
> 当geyser与proxy及master正常连接时,会输出如下日志
|
||||
|
||||

|
||||
|
||||
> 当玩家正常登录上proxy及geyser时,会输出如下日志
|
||||
|
||||
1、当玩家登录时没有图示输出时,请检查master、proxy和geyser的配置及日志,检查是否有报错打印
|
||||
2、当玩家登录时有图示输出,但是玩家无法正常进服,请检查geyser、bc、spigot相关配置及日志,检查是否有报错打印
|
||||
|
||||

|
||||
|
||||
36
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/99-下载内容.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 分钟
|
||||
---
|
||||
|
||||
# 下载内容
|
||||
|
||||
## BungeeMaster插件
|
||||
[下载链接](https://g79.gdl.netease.com/BungeeMaster-1.0.2-SNAPSHOT.jar)
|
||||
|
||||
bc服插件,必须,用于bc服组网
|
||||
|
||||
版本:1.0.2-SNAPSHOT
|
||||
|
||||
更新日期:2022.10.18
|
||||
|
||||
|
||||
|
||||
## SpigotMaster插件
|
||||
|
||||
[下载地址](https://g79.gdl.netease.com/SpigotMaster-1.2-SNAPSHOT.jar)
|
||||
|
||||
spigot服插件,可选,用于客户端python通信,自定义物品
|
||||
|
||||
版本:1.2-SNAPSHOT
|
||||
|
||||
更新日期:2022.10.18
|
||||
|
||||
|
||||
|
||||
## 示例Demo
|
||||
|
||||
[下载地址](https://g79.gdl.netease.com/Apollo2.0Demo01.zip)
|
||||
|
||||
更新日期:2022.10.18
|
||||
0
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/README.md
Normal file
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/SpigotProperty/sp01.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/SpigotProperty/sp02.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/bc01.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/bc02.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/bc03.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/bc04.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/bc05.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/bc06.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/demo1.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/frame.png
Normal file
|
After Width: | Height: | Size: 117 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest1.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest2.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest3.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest4.png
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest5.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest6.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest7.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/quest8.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 329 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 246 KiB |
|
After Width: | Height: | Size: 174 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin1.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 887 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 73 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin2.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 54 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin3.png
Normal file
|
After Width: | Height: | Size: 424 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin4.png
Normal file
|
After Width: | Height: | Size: 721 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin5.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin6.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin7.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin8.png
Normal file
|
After Width: | Height: | Size: 251 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/spigotPlugin/plugin9.png
Normal file
|
After Width: | Height: | Size: 269 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/studio1.png
Normal file
|
After Width: | Height: | Size: 164 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/studio2.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/studio3.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/studio4.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/mcguide/27-网络游戏/课程8:使用Spigot开服/res/studio5.png
Normal file
|
After Width: | Height: | Size: 61 KiB |