# 十分钟上手GeekServer

# 运行
1. 安装[.NetCore6.0](https://dotnet.microsoft.com/download/dotnet/6.0)
2. 安装[mongodb4.x](https://www.mongodb.com/try/download/community)
3. 打开git clone本项目https://github.com/leeveel/GeekServer.git
4. 运行Tools/ExcelGen/ExcelToCode.exe 点击[服务器-ALL]导出配置表
5. 用VisualStudio2022打开GeekServer.sln 启动GeekServer.App
6. 启动GeekServer.TestPressure (一个1000人登录的demo)
7. 打开UnityDemo工程，打开SampleScene，运行查看日志(**检查Main Camera上是否有脚本丢失，如果有请挂载GameMain.cs**)


## 如何添加新功能

### 1.规划线程模型  
以demo为例，demo中有两个Actor(可以理解为逻辑上的线程)，一个是Server，另外一个是Role，Server线程是全局的一个服务器只会存在一个，而Role则是一个玩家一个线程。在demo中Server线程负责了登录以及世界等级相关逻辑(实际开发中规划一个LoginActor比较合理)，于是为Server注册了LoginComp和ServerComp两个组件。对于Role来说，一个玩家会存在很多功能系统，如角色模块，背包模块，宠物模块，所有为Role注册RoleComp，BagComp，PetComp。  
**也就是说一个功能系统的逻辑是运行在哪个线程上，取决于你把这个功能系统的组件注册在哪个Actor上。**
### 2.如何为Actor注册组件  
通过Comp注解为Actor注册组件   
[Comp(ActorType.Role)]   
public class BagComp : StateComp<BagState>
### 3.如何绑定组件状态(数据)  
一个功能系统由两部分组成，1是逻辑代码(xxxCompAgent)，2是数据(xxxState)，为了实现逻辑代码的热更新，GeekServer使用了代理的方式将逻辑与数据分离。以下代码展示组件和数据的绑定方式：  
[Comp(ActorType.Role)]   
public class BagComp : StateComp<BagState>  
public class BagCompAgent : StateCompAgent<BagComp, BagState>

### 4.如何监听事件  
请参见Geek.Server.Role.PetCompAgent
### 5.如何添加定时器 
请参见Server.Logic.Logic.ServerCompAgent
### 6.为需给外部提供服务的接口添加[Api]注解 
请参见Server.Logic.Logic.ServerCompAgent.GetWorldLevel()接口，此接口是获取服务器世界等级，由于这个接口会对外部提供服务，即其他Actor都有可能访它，所以需要添加[Api]注解

## 方法注解
**[Api]**：代表此接口需要被其他Actor调用  
**[Discard]**：代表在调用此接口的时候，会使用弃元运算符(_ = DoSomething()),**因为弃元运算符会导致执行此异步函数逻辑的线程不可确定，所以GeekServer对标记了[Discard]注解的处理方式是，强制插入队列末端执行。**   
**[ThreadSafe]**：代表此接口是线程安全的，不是必须的，而且应该尽量少用(1.让逻辑开发人员尽量少关注多线程 2.如果标注的接口逻辑很复杂，再代码多次迭代之后，很容易误判)  
**[TimeOut(30000)]**：可以自定义接口的超时时间  
具体代码请参见Server.Logic.Logic.ServerCompAgent

## 关于Message.Unid
在demo中可以看到客户端的ReqXXX消息，在服务器回包当中，都带上了ReqXXX传过来的Unid。demo中这个设计为了解决自动处理客户端(发送消息->锁屏->收到回包->解锁屏)的逻辑。**如果你有自己的方案或者不需要此设计忽略它**。

### 至此已经足够你基于GeekServer开发自己的游戏功能





