feat:上传mcguide-开发指南部份

This commit is contained in:
Othniel su
2024-12-23 10:57:59 +08:00
parent 7292166c88
commit 0dc59fa4f0
3297 changed files with 63375 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@@ -0,0 +1,202 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/help_ui_04.8f59f5ac.png
hard: 进阶
time: 20分钟
---
# UI界面表现提升技巧
## 实现UI管理器对象
* UI界面要最终显示需要经历【注册】【创建】【显示】这三个关键步骤并且这三个关键步骤是可以分离的。
### UI界面的【注册】
* 通过API【RegisterUI】注册一个UI界面在没有卸载Mod的情况下同一UI只需要注册一次
* 经测试,注册界面消耗的时间,与界面本身的复杂度(控件数量、用到的资源图片)基本无关,是一个相对稳定的均值。
### UI界面的【创建】
* 通过API【CreateUI】创建一个UI界面在没有卸载Mod并且没有调用API【SetRemove】销毁界面的情况下同一个UI只需要创建一次
* 创建UI界面的整个流程中在生成了UI上的全部控件之后会调用UI界面对应的类的【Create】成员函数一般会在这个成员函数中对按钮的响应等功能进行初始化假如【Create】成员函数中执行了【Clone】等消耗较大的API 那么也会拖慢整个UI的创建流程
* 经测试创建界面消耗的时间受界面本身的复杂度影响一个UI界面包含的控件数量越多创建的速度就越慢一个UI界面使用到的图片资源的总尺寸越大创建的速度就越慢
* 一般来说单个不是特别复杂的UI界面的创建时间在10-40ms之间按照游戏帧率30来计算每帧的平均时间为33ms40ms左右的时间刚刚好不至于产生能够感知到的卡顿。
### UI界面的【显示】
* 通过API【SetScreenVisible】显示/隐藏一个UI界面。
* 在UI界面已经完成创建的情况下仅仅使用API【SetScreenVisible】显示一个UI界面基本都仅仅消耗1ms左右。
* 经测试对UI里面的控件的具体显示功能进行调整那么消耗的时间回合具体调整的内容相关。
* 对图片控件进行【SetVisible】、【SetSprite】等操作消耗的时间与对应的图片资源的尺寸相关
* 对文本控件进行【SetText】、【SetTextColor】等操作消耗的时间与文本的总长度相关并且设置中文比设置纯英文和数字慢得多。
* 对控件进行【Clone】操作与控件本身的复杂度子控件的数量正相关。
### UI界面的【销毁】
* 通过API【SetRemove】销毁一个UI界面调用【SetRemove】之后需要重新【CreateUI】后才能显示这个UI。
* 经测试【SetRemove】消耗的时间在1-3ms左右基本不太可能导致可感知的客户端卡顿。
### 管理器代码示例
* 使用管理器分离UI界面的【注册】、【创建】和【显示】可以有效避免**同时大量创建界面**的情况发生,避免客户端出现可感知的卡顿。
* 管理器基于**Create On Use**的原则设计,通过管理器获取/显示UI界面可以基本保证**同一时间仅创建一个UI**与**每个UI仅创建一次**
* 管理器提供**CleanCacheUI**函数可以在合适的时候调用释放已经完成【创建】的UI界面以释放内存占用。
```
class UIDef:
UIBig1 = "UIBig1"
UIBig2 = "UIBig2"
...
UIData = {
UIDef.UIBig1 : {
"cls":"neteaseUiSampleScript.ui.netease_uisample_big.UiSampleScreen",
"screen":"netease_uisample_big01.main",
"isHud":1,
"layer":clientApi.GetMinecraftEnum().UiBaseLayer.PopUpLv1,
},
UIDef.UIBig2 : {
"cls":"neteaseUiSampleScript.ui.netease_uisample_big.UiSampleScreen",
"screen":"netease_uisample_big03.main",
"isHud":1,
"layer":clientApi.GetMinecraftEnum().UiBaseLayer.PopUpLv1,
},
UIDef.UIBig3 : {
...
}
class UIMgr(object):
def __init__(self):
super(UIMgr, self).__init__()
self.mModName = "NeteaseUiSample"
self.mUIDict = {}
self.mClientSystem = None
def Destroy(self):
pass
# UI管理器的初始化一般在客户端引擎事件【UiInitFinished】的回调中调用
def Init(self, system):
self.mClientSystem = system
# 在初始化时执行所有可能用到的UI的【注册】环节
# UI的【注册】环节消耗比较大在初始化时执行主要是因为客户端初始化的整个流程一般会消耗好几秒额外消耗几十到一百多毫秒用来【注册】UI界面影响不是很大。
for uiKey, config in UIData.iteritems():
cls, screen = config["cls"], config["screen"]
clientApi.RegisterUI(self.mModName, uiKey, cls, screen)
# 封装了UI的【创建】过程
def CreateSingleUI(self, uiKey):
config = UIData.get(uiKey, None)
if not config:
return None
extraParam = {}
if config.has_key("isHud"):
extraParam["isHud"] = config["isHud"]
ui = clientApi.CreateUI(self.mModName, uiKey, extraParam)
if not ui:
return None
layer = config.get("layer", None)
if not layer is None:
ui.InitLayer(layer)
ui.InitSystem(self.mClientSystem, uiKey)
ui.InitScreen()
# 缓存已经完成【创建】的UI
self.mUIDict[uiKey] = ui
return ui
def GetUI(self, uiKey):
# 优先从缓存中获取UI界面对象
ui = self.mUIDict.get(uiKey, None)
if ui:
return ui
# 假如没有缓存,那么新【创建】一个
return self.CreateSingleUI(uiKey)
# 【显示】一个UI界面
# 假如UI还没有【创建】过那么先执行【创建】流程
# 假如UI已经完成了【创建】那么直接从缓存中获取UI实例
# 在一般的应用中只有第一次【显示】UI界面的时候才会附带一个额外的【创建】流程
# 之后的再次【显示】界面,就不需要再次【创建】界面,大大提升界面【显示】的速度
def ShowUI(self, uiKey):
ui = self.GetUI(uiKey)
if not ui:
return
ui.Show()
def CleanCacheUI(self):
if not self.mUIDict:
return
for uiKey, ui in self.mUIDict.iteritems():
ui.SetRemove()
self.mUIDict.clear()
def RemoveUI(self, uiKey):
ui = self.mUIDict.get(uiKey, None)
if not ui:
return False
del self.mUIDict[uiKey]
ui.SetRemove()
return True
```
## 使用pushScreen优化单个UI的创建
* API【pushScreen】整合了UI界面的【创建】和【显示】两个环节只需要【注册】和【pushScreen】即可显示一个UI
* 对于同一个UI界面【pushScreen】不建议与【CreateUI】混用
* 【pushScreen】只能同时显示一个UI界面在一个UI界面显示的状态下调用【pushScreen】显示另外一个UI界面会自动隐藏之前的UI界面
* 使用【pushScreen】【创建】并【显示】一个UI界面实际上是一个异步的过程所以相对于【CreateUI】方法来说整个界面的【创建】工作是分时完成的可以最大限度地防止客户端卡顿地现象发生。
* 【CreateUI】的执行流程
![](./images/help_ui_01.png)
* 【pushScreen】的执行流程
![](./images/help_ui_02.png)
* 【pushScreen】【创建】界面是一个异步的过程从流程图上可见必须等待引擎调用注册时输入的ScreenNode类的【Create】成员函数后界面的初始化工作才完成之后才能正常地对界面上地控件进行各种调整。
## 其他小技巧
### 使用九宫贴图替代大尺寸贴图
* 当前UI编辑器中已经提供了非常好用的九宫拉伸预览功能使用九宫拉伸可以用很小尺寸的贴图实现各种背景贴图效果
![](./images/help_ui_03.png)
使用一张32X64的小尺寸贴图通过九切拉伸可以展现出297X198的背景图效果如下图
![](./images/help_ui_04.png)
### 拆分含有分页的复杂界面
* 经测试单个UI界面【创建】和【显示】需要消耗的时间受整个UI界面中的控件总数影响最大控件总数越多【创建】和【显示】消耗的时间越大。
* 那么当一个界面上由于功能太多,导致控件太多,最终导致【创建】【显示】消耗时间太多导致客户端出现卡顿时,就可以尝试把一个界面拆分为多个子界面的方式来优化客户端表现。
* 以领地插件为例,下面是领地插件界面的示意图
![](./images/help_ui_05.png)
* 可见界面整体是非常复杂的,每个分页上面就含有很多控件,并且整个界面还有五个分页
![](./images/help_ui_06.png)
* 为了优化整个界面的实际表现从UI的工程上就可以看到事实上每个分页都是一个独立的子界面表面上切换分页的行为最终在代码上实际是用隐藏一个界面然后显示另外一个界面的方式来实现的。
示例代码如下:
```python
def OnApplyBtn(self, args):
"""
切换领地界面到【申请权限】分页
"""
touchEvent = args["TouchEvent"]
touch_event_enum = extraClientApi.GetMinecraftEnum().TouchEvent
if touchEvent == touch_event_enum.TouchUp:
for keys in uiDef.UIData.keys():
if keys != uiDef.UIDef.UIResidenceApply:
ui = self.mUIMgr.GetUI(keys)
ui.ClosePanel()
ui = self.mUIMgr.GetUI(uiDef.UIDef.UIResidenceApply)
if ui:
ui.Show()
```
### 分时执行Clone等高消耗的操作
* 经测试,【创建】并【显示】下面的背景图+一个组合控件+一个ScrollView+一些按钮消耗的时间仅为Clone100个组合控件的1/25在一般配置的PC环境【创建】并【显示】消耗36ms而Clone100个组合控件消耗867ms
![](./images/help_ui_07.png)
* 那么当最终想要下图所示的含有100个组合控件的界面时最好是最初时候仅【创建】并【显示】不含有组合控件的简单界面初始化成员函数【Create】中隐藏组合控件的原型
![](./images/help_ui_08.png)
* 然后在接下来的几十帧中每帧创建个5-10个组合控件直到全部创建完成
示例代码如下:
```python
def PlusSomePart(self, plusNum):
baseOffset = len(self.mOnUseParts)
basePos, baseSize = self.mScrollData["partBasePos"], self.mScrollData["partBaseSize"]
offset = self.mScrollData["partBaseOffset"]
for i in xrange(plusNum):
data = self.GetFreePart()
pos = (basePos[0], basePos[1]+(baseSize[1]+offset)*(baseOffset+i))
baseUIControl = self.GetBaseUIControl(data["fullName"])
baseUIControl.SetPosition(pos)
baseUIControl.SetVisible(True)
self.mOnUseParts.append(data["id"])
self.ResizeScroll()
def OnButtonAsyncPlus(self, plusNum, args):
self.mAyncPlusLeftNum += plusNum
def Update(self):
if self.mAyncPlusLeftNum <= 0:
return
plusNum = min(5, self.mAyncPlusLeftNum)
self.mAyncPlusLeftNum -= plusNum
self.PlusSomePart(plusNum)
```
### 主动使用过渡性的加载进度界面
* UI界面在客户端Mod没有卸载的情况下仅需要【注册】、【创建】一次之后就可以多次重复【显示/隐藏】。
* 经测试,对比【注册】【创建】行为,【显示/隐藏】消耗的时间基本都是10ms以内哪怕此界面控件繁多逻辑复杂。
* 可以在游戏启动后主动添加一个带进度条的全屏界面使用每帧【注册】并【创建】一个UI界面的方法把需要用到的界面全部创建好那么在游戏过程中仅调用【显示/隐藏】功能的界面就不会卡顿了。

View File

@@ -0,0 +1,45 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/zdbs02.2d2c4f75.png
hard: 进阶
time: 20分钟
---
# 多账号协同部署
### 概述
团队开发过程中,可能需要协同提交代码、美术资源等内容,而这些内容可能涉及一定的查看权限。“**自动部署**”功能可便捷解决该问题,简要描述如下:
1开发者自行通过版本维护工具在某个本地目录进行协同提交。
2主账号可对该目录开启自动部署定期检测该目录内容若存在更新则执行部署操作。
### 自动部署流程
- 主账号右键点击网络服,选择“更多——自动部署”
![](./images/zdbs01.png)
- 按开发者所用的版本工具调整自动更新命令。默认为svn update也支持git或其他版本工具指令。
![](./images/zdbs02.png)
- 点击“开启自动部署”按钮,可开启自动部署功能。开启后,点击“自动部署记录”可查看自动部署结果。
![](./images/zdbs03.png)
- 对于自动部署中的网络游戏,点击“关闭自动部署”按钮,可关闭自动部署功能。
- 对于子账号,也能查看自动部署日志。
![](./images/zdbs04.png)

View File

@@ -0,0 +1,63 @@
---
front:
hard: 进阶
time: 20分钟
---
# 控制台调试
### 应用场景
控制台调试集成了三项功能脚本测试、原版指令输入、POST指令输入。可在开发阶段使用。
- 脚本测试便于加载mod的时候额外执行脚本获取关注的变量或返回值。
- 原生指令:可在指定的服务器类型,执行原生指令。
- POST指令POST指令是Apollo网络服的自定义指令固定在控制服Master执行。
### 控制台调试入口
右键点击正在运行的网络服,选择“控制台调试”。
![](./images/cmd1.png)
### 脚本测试
在脚本测试分页,选定要执行脚本的服务器类型,然后再输入文本框中输入测试脚本,点击“发送”按钮,执行结果在右侧输出区域显示。
*举例如下在控制服输入控制服APIGetGameTypeByServerId()该API的作用是获取指定ID服务器的类型。*
![](./images/cmd6.png)
### 原生指令
在原生指令分页,选定要执行脚本的服务器类型,然后再输入文本框中输入测试脚本,点击“发送”按钮,执行结果在右侧输出区域显示。
*举例如下在大厅服输入原生的tp指令*
![](./images/cmd4.png)
### POST指令
在POST指令分页选定要执行脚本的服务器类型然后再输入文本框中输入测试脚本点击“发送”按钮执行结果在右侧输出区域显示。
鉴于POST指令过于复杂提供了预设指令的功能。点击“选择指令”按钮可预览预设指令。
![](./images/cmd9.png)
其中插件中的自定义指令可通过在modRequest.json中指定。以官方的喇叭公告插件为例modRequest.json位于neteaseShout目录之下。文件格式如下
![](./images/cmd7.png)
![](./images/cmd11.png)
![](./images/cmd12.png)

View File

@@ -0,0 +1,77 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/zdbs02.2d2c4f75.png
hard: 进阶
time: 5分钟
---
# 子账号部署和控制台调试功能
### 概述
团队开发过程中,可能需要协同部署和测试,涉及到一定的权限管理。
### 可实现的效果
- 主账号拥有完全权限
- 子账号被赋予了主账号开发及审核阶段的部署权限:对这些赋予权限的服务器,拥有除删除以外的所有权限
- 子账号被赋予了主账号上线阶段调试权限:对这些赋予权限的服务器,拥有调试和查看日志的权限
### 权限设置
- 在开发者平台进行子账号的管理,可以在这里设置
- 子账号在开发阶段与审核阶段是否允许配置,部署和热更服务器
- 子账号在上线阶段是否允许使用控制台调试
![image-20220411193031517](./images/image-20220411193031517.png)
### 多个子账号协同
如果多个账号同时对一个服务器进行部署,或者服务器配置等操作,会导致冲突。为了避免此类冲突,我们引入了一套锁定机制。
需要执行这些操作的账号需要先锁定服务器,才能进行,而其他账号不能对锁定中的服务器进行部署,配置等操作。
1. 如果一个服务器没有完成配置,那么你只能进行开发测试等功能。
![image-20220411202033275](./images/image-20220411202033275.png)
2. 如果想要进行配置,你必须先点击锁定。完成对服务器的锁定后,其他开发者进行配置或部署将失败。
![image-20220411202352736](./images/image-20220411202352736.png)
3. 锁定后,如上图,你可以对这个服务器进行配置。配置结束后,可以对这个服务器进行部署操作。
![image-20220411202445382](./images/image-20220411202445382.png)
4. 如果你的服务器处于可部署,但是未锁定的状态,如下图,你也必须先锁定,才能进行部署操作。
![image-20220411202033275](./images/image-20220411202033275.png)
5. 当你需要的操作配置部署等都执行完毕的时候请即时解锁避免影响其他账号使用。解锁有两种方式一种是直接点击服务器封面的解锁按钮见下图1另一种是右键或者点击服务器封面的更多按钮在菜单中选择解除锁定。
![image-20220411202352736](./images/image-20220411202352736.png)
![image-20220411203104534](./images/image-20220411203104534.png)
6. 工作台不会即时同步锁定状态,所以有可能出现当你希望执行某操作的时候,可能出现服务器已经被其他账号锁定的情况,会弹出如下的提示。此时,如果你需要执行操作,需要自主联系对方解锁。
![image-20220411203212061](./images/image-20220411203212061.png)
7. 如果你是主账号你有强制解锁服务器的权限。被强制解锁的子账号在3min中内不能再上锁这个服务器。
![image-20220412161046230](./images/image-20220412161046230.png)
### 子账号运营日志权限管理
- 主账号可以在工作台中指定每个运营指令是否允许子账号操作
- 当复制服务器到审核阶段,上线阶段时,运营指令的设置也会被继承
![image-20220411204137558](./images/image-20220411204137558.png)