
作用:简单的开始,以MyGameServer为例,最终目的生成类库.dll给server用
新建项目—Visual C#—类库—写个名字MyGameServer—创建
这是dll后缀文件,不可以自己启动的
解决方案资源管理器—MyGameServer项目—右键—生成
可以在MyGameServer-MyGameServer-bin-Debug里生成dll文件
项目MyGameServer—属性
看是否.NET4.5
Photon路径:
C:\Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy
1、
deploy文件夹里新建文件夹MyGameServer
2、
MyGameServer文件夹里新建文件夹bin
bin不可改名字
项目MyGameServer—属性—生成—输出—输出路径
为上面的bin
ctrl + S 保存一下
解决方案资源管理器—MyGameServer项目—引用—右键—添加引用—浏览—浏览—目标C/D盘—Photon-OnPremise-Server-SDK_v4-0-29-11263—lib
引用5个:
ExitGamesLibs.dll—————————————Photon
Photon.StocketServer.dll——————————Photon
PhotonHostRuntimeInterfaces.dll——————-Photon
ExitGames.Logging.Log4Net.dll——————-日志的
log4net.dll————————————————-日志的
骚操作:解决方案资源管理器—MyGameServer项目—管理NuGet程序包里搜
找C:\Photon-OnPremise-Server-SDK_v4-0-29-11263\src-server\Mmo\Photon.MmoDemo.Server
里的log4net.config—复制ctrl+c
vs—解决方案资源管理器—点击一下MyGameServer项目—黏贴ctrl+v
让log4net.config与类在一个目录
点击一下log4net.config—属性—高级—复制到输出目录—始终复制
让信息复制到C:\Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy\MyGameServer\bin
修改文件第5行
这个文档的百分号是错误的,不要复制
value="\\\\\\\\\\\\\\\\\\\\\\\\\\\%property{Photon:ApplicationLogPath}\\MyGame.Server.log" /> #######修改名字mmo-MyGame
可以删除Class1.cs
解决方案资源管理器—MyGameServer项目—Class1.cs
解决方案资源管理器—MyGameServer项目—右键—添加—新建项—类
名字一般与项目名称相同MyGameServer.cs—添加
以至于namespace与class都是MyGameServer
class MyGameServer前加上public,外界可以访问
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Photon.SocketServer;using ExitGames.Logging;using ExitGames.Logging.Log4Net;using System.IO;using log4net.Config;namespace MyGameServer{//所有的server端都要继承ApplicationBasepublic class MyGameServer : ApplicationBase{public static readonly ILogger log = LogManager.GetCurrentClassLogger();//当一个peer客户端请求链接的时候创建peerbaseprotected override PeerBase CreatePeer(InitRequest initRequest){return new ClientPeer(initRequest);}//初始化protected override void Setup(){//日志的初始化log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(this.ApplicationRootPath, "log");FileInfo configFileInfo = new FileInfo(Path.Combine(this.BinaryPath,"log4net.config"));if (configFileInfo.Exists){LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);//让Photon知道XmlConfigurator.ConfigureAndWatch(configFileInfo);//让log4net这个插件读取配置文件}log.Info("初始化完成");}//server端关闭的时候protected override void TearDown(){}}}
设置了日志
MyGame.Server.log————————程序自己配置的信息输出
C:\Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy\log\MyGame.Server.log
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Photon.SocketServer;using ExitGames.Logging;using ExitGames.Logging.Log4Net;using System.IO;using log4net.Config;using MyGameServer.Manager;using Common;using MyGameServer.Handler;using MyGameServer.Threads;namespace MyGameServer{//所有的server端 主类都要集成自applicationbasepublic class MyGameServer:ApplicationBase{//日志C:\Users\chu\Desktop\Mygame\MyGameServer\MyGameServer.cspublic static readonly ILogger log = LogManager.GetCurrentClassLogger();public static MyGameServer Instance//单例模式检测进来的code是什么{get;//外面只可以获取到private set;里面可以修改}public Dictionary<OperationCode, BaseHandler> HandlerDict = new Dictionary<OperationCode, BaseHandler>();public List<ClientPeer> peerList = new List<ClientPeer>();//通过这个集合可以访问到所有客户端的peer,从而向任何一个客户端发送数据private SyncPositionThread syncPositionThread = new SyncPositionThread();//实例化线程//当一个客户端请求链接的//我们使用peerbase,表示和一个客户端的链接protected override PeerBase CreatePeer(InitRequest initRequest){log.Info("一个客户端连接过来了。。。。");ClientPeer peer = new ClientPeer(initRequest);peerList.Add(peer);//保存在服务器return peer;}//server端初始化的时候protected override void Setup(){Instance = this;// 日志的初始化log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(this.ApplicationRootPath, "log");FileInfo configFileInfo = new FileInfo( Path.Combine( this.BinaryPath ,"log4net.config"));if (configFileInfo.Exists){LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);//让photon知道XmlConfigurator.ConfigureAndWatch(configFileInfo);//让log4net这个插件读取配置文件}log.Info("服务器开启了!");InitHandler();//初始化-收信息syncPositionThread.Run();//线程开启}public void InitHandler(){//登录LoginHandler loginHandler = new LoginHandler();HandlerDict.Add(loginHandler.OpCode, loginHandler);//错误找不到时用一个默认的来处理DefaultHandler defaultHandler = new DefaultHandler();HandlerDict.Add(defaultHandler.OpCode, defaultHandler);//注册RegisterHandler registerHandler = new RegisterHandler();HandlerDict.Add(registerHandler.OpCode, registerHandler);//位置更新SyncPositionHandler syncPositionHandler = new SyncPositionHandler();HandlerDict.Add(syncPositionHandler.OpCode, syncPositionHandler);//其他玩家的信息SyncPlayerHandler syncPlayerHandler = new SyncPlayerHandler();HandlerDict.Add(syncPlayerHandler.OpCode, syncPlayerHandler);}//server端关闭的时候protected override void TearDown(){syncPositionThread.Stop();//线程结束log.Info("服务器应用关闭了");}}}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Photon.SocketServer;using PhotonHostRuntimeInterfaces;namespace MyGameServer{public class ClientPeer:Photon.SocketServer.ClientPeer{public ClientPeer(InitRequest initRequest) : base(initRequest){}//客户端断开连接protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail){}//客户端连接protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters){switch (operationRequest.OperationCode)//通过OperationCode区分请求{case 1:MyGameServer.log.Info("收到客户端发送的一个请求");//得到参数Dictionary<byte, object> data = operationRequest.Parameters;object intValue;data.TryGetValue(1, out intValue);object stringValue;data.TryGetValue(2, out stringValue);MyGameServer.log.Info("参数:"+ intValue.ToString()+ stringValue.ToString());//加上参数回去OperationResponse opResponse = new OperationResponse(1);Dictionary<byte, object> data2 = new Dictionary<byte, object>();data2.Add(1, 100);//加数据data2.Add(2, "aaBB中文");//加数据opResponse.SetParameters(data2);SendOperationResponse(opResponse, sendParameters);//给客户端一个响应break;default:break;}}}}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Photon.SocketServer;using Common.Tools;using Common;using MyGameServer.Handler;//客户端namespace MyGameServer{public class ClientPeer:Photon.SocketServer.ClientPeer{public float x, y, z;//位置信息public string username;public ClientPeer(InitRequest initRequest):base(initRequest){}//处理客户端断开链接的后续工作protected override void OnDisconnect(PhotonHostRuntimeInterfaces.DisconnectReason reasonCode, string reasonDetail){MyGameServer.Instance.peerList.Remove(this);}//处理客户端的请求protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters){//实例化(获得请求码)BaseHandler handler = DictTool.GetValue<OperationCode, BaseHandler>(MyGameServer.Instance.HandlerDict, (OperationCode)operationRequest.OperationCode);//MyGameServer的字典和事情码组成字典if (handler != null){handler.OnOperationRequest(operationRequest, sendParameters, this);}else{BaseHandler defaultHandler = DictTool.GetValue<OperationCode, BaseHandler>(MyGameServer.Instance.HandlerDict, OperationCode.Default);defaultHandler.OnOperationRequest(operationRequest, sendParameters, this);}}}}
C:\Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy\bin_Win64\PhotonControl
1、有没有”初始化完成”
2、Server is running