服务器篇
1.服务器windows10 64位启动路径:
C:\PrivateSpace\PhotonServer\Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy\bin_Win64\PhotonControl.exe
2.服务器Ip配置,在统计目录的PhotonServer.config 中添加
<!-- 0.0.0.0 opens listeners on all available IPs. Machines with multiple IPs should define the correct one here. -->
<!-- Port 5055 is Photon's default for UDP connections. -->
<UDPListeners>
<UDPListener
IPAddress="0.0.0.0"
Port="5055"
OverrideApplication="MyGame1">
</UDPListener>
</UDPListeners>
<!-- 0.0.0.0 opens listeners on all available IPs. Machines with multiple IPs should define the correct one here. -->
<!-- Port 4530 is Photon's default for TCP connecttions. -->
<!-- A Policy application is defined in case that policy requests are sent to this listener (known bug of some some flash clients) -->
<TCPListeners>
<TCPListener
IPAddress="0.0.0.0"
Port="4530"
PolicyFile="Policy\assets\socket-policy.xml"
InactivityTimeout="10000"
OverrideApplication="MyGame1"
>
</TCPListener>
</TCPListeners>
<!-- Defines the Photon Runtime Assembly to use. -->
<Runtime
Assembly="PhotonHostRuntime, Culture=neutral"
Type="PhotonHostRuntime.PhotonDomainManager"
UnhandledExceptionPolicy="Ignore">
</Runtime>
<!-- Defines which applications are loaded on start and which of them is used by default. Make sure the default application is defined. -->
<!-- Application-folders must be located in the same folder as the bin_win32 folders. The BaseDirectory must include a "bin" folder. -->
<Applications Default="MyGame1">
<!-- MMO Demo Application -->
<Application
Name="MyGame1"
BaseDirectory="MyGameServer"
Assembly="MyPhServer"
Type="MyPhServer.MyGameServer"
ForceAutoRestart="true"
WatchFiles="dll;config"
ExcludeFiles="log4net.config">
</Application>
</Applications>
添加自己新加游戏的配置。 其他配置网络上有详细的教程,可以学习一步一步做 **3.服务器代码的构建:** 服务器程序的创建:服务器主程序类 using Photon.SocketServer; using ExitGames.Logging; using System.IO; using ExitGames.Logging.Log4Net; using log4net.Config; using System.Collections.Generic;
namespace MyPhServer
{
public class MyGameServer : ApplicationBase
{
public static readonly ILogger log = LogManager.GetCurrentClassLogger();
public static List Peers = new List();
//当一个客户链接的时候
protected override PeerBase CreatePeer(InitRequest initRequest)
{
log.Info("一个客户端链接成功!!! ");
var peer = new MyClientPeer(initRequest);
Peers.Add(peer);
return peer;
}
//服务器初始化的时候
protected override void Setup()
{
//日志的初始化
log4net.GlobalContext.Properties[“Photon:ApplicationLogPath”] = Path.Combine(Path.Combine(this.ApplicationRootPath, “bin_Win64”),“log”);
FileInfo cfFileInfo = new FileInfo(Path.Combine(this.BinaryPath,“log4net.config”));
if (cfFileInfo.Exists)
{
LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);
XmlConfigurator.ConfigureAndWatch(cfFileInfo);
}
ModelManager.Instance.OnInit();
log.Info("Setup Completed! ");
}
//服务器关闭的时候
protected override void TearDown()
{
ModelManager.Instance.OnDispos();
log.Info("服务器关闭了! ");
}
}
}
4.单独一个玩家链接的实例:
using Common;
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
namespace MyPhServer
{
public class MyClientPeer : ClientPeer
{
public MyClientPeer(InitRequest initRequest):base(initRequest){}
//断开链接
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
MyGameServer.Peers.Remove(this);
}
//客户端请求操作
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
byte code = operationRequest.OperationCode;
ModelManager.Instance.OnReq(this,(OperationCode)code, operationRequest.Parameters);
}
}
}
5.各个模块的基类:
using Common;
using Photon.SocketServer;
using System.Collections.Generic;
namespace MyPhServer
{
public class ModelManager
{
private static ModelManager instance;
public static ModelManager Instance { get { if (instance == null) instance = new ModelManager(); return instance; } }
private Dictionary<OperationCode, ReqHandleBase> Handlers = new Dictionary<OperationCode, ReqHandleBase>();
public void OnInit()
{
var reg = new AccountReg();
Handlers.Add(OperationCode.Reg, reg);
var login = new AccountLogin();
Handlers.Add(OperationCode.Login, login);
var chatList = new ChatListReq();
Handlers.Add(OperationCode.ChatList, chatList);
var chatReq = new ChatReq();
Handlers.Add(OperationCode.Chat, chatReq);
var roomCreatReq = new RoomCreatReq();
Handlers.Add(OperationCode.RoomCreat, roomCreatReq);
var roomJoinReq = new RoomJoinReq();
Handlers.Add(OperationCode.JoinRoom, roomJoinReq);
var roomListReq = new RoomListReq();
Handlers.Add(OperationCode.RoomList, roomListReq);
var roomLeavlReq = new RoomLeavlReq();
Handlers.Add(OperationCode.LeavlRoom, roomLeavlReq);
var roomEnterReq = new RoomEnterReq();
Handlers.Add(OperationCode.EnterRoom, roomEnterReq);
var roomReadyReq = new RoomReadyReq();
Handlers.Add(OperationCode.ReadyRoom, roomReadyReq);
var roomUnReadyReq = new RoomUnReadyReq();
Handlers.Add(OperationCode.UnReadyRoom, roomUnReadyReq);
var BattleInfo = new BattleInfo();
Handlers.Add(OperationCode.BattleInfo, BattleInfo);
var AllBattleInfo = new AllBattleInfo();
Handlers.Add(OperationCode.AllBattleInfo, AllBattleInfo);
var creatBotReq = new RoomCreatBotReq();
Handlers.Add(OperationCode.CreatBot, creatBotReq);
var setCamp = new RoomSetCampReq();
Handlers.Add(OperationCode.SetCamp, setCamp);
}
public void OnDispos()
{
Handlers.Clear();
}
public void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
MyGameServer.log.Info("收到客户端请求!!!code is :" + pCode);
if (Handlers.ContainsKey(pCode))
{
ReqHandleBase handleBase = Handlers[pCode];
handleBase.OnReq(pPeer, pCode, pData);
}
}
}
}
6.所有模块的处理请求基类:
using Common;
using Photon.SocketServer;
using System.Collections.Generic;
namespace MyPhServer
{
public class ReqHandleBase
{
public object GetParamerers(Dictionary<byte, object> pData, byte pIndex)
{
object value;
pData.TryGetValue(pIndex, out value);
return value;
}
public virtual OperationCode OpCode {get { return OperationCode.Login; }}
public virtual void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
}
public virtual void SenhdAllInRoomNotMe(ClientPeer pPeer, EventCode pEventCode, ParamsCode pCode, object pParms, SendParameters sendParameters)
{
EventData eventData = new EventData((byte)pEventCode);
Dictionary<byte, object> data = new Dictionary<byte, object>();
data[1] = (byte)pCode;
data[2] = pParms;
eventData.SetParameters(data);
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
var room = RoomManager.Instance.GetInRoom(playerId);
if (room != null)
{
var playerIds = room.PlayerIds;
foreach (var temp in playerIds)
{
var peer = UserManager.Instance.GetClientPeerByPlayerId(temp);
if (peer != null && peer != pPeer)
{
peer.SendEvent(eventData, new SendParameters());
}
}
}
}
public virtual void SendAllInRoom(ClientPeer pPeer, EventCode pEventCode, ParamsCode pCode, object pParms, SendParameters sendParameters)
{
EventData eventData = new EventData((byte)pEventCode);
Dictionary<byte, object> data = new Dictionary<byte, object>();
data[1] = (byte)pCode;
data[2] = pParms;
eventData.SetParameters(data);
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
var room = RoomManager.Instance.GetInRoom(playerId);
if (room != null)
{
var playerIds = room.PlayerIds;
foreach (var temp in playerIds)
{
var peer = UserManager.Instance.GetClientPeerByPlayerId(temp);
if (peer != null)
{
peer.SendEvent(eventData, new SendParameters());
}
}
}
}
public virtual void OnSendAll(ClientPeer pPeer, EventCode pEventCode, ParamsCode pCode, object pParms, SendParameters sendParameters)
{
EventData eventData = new EventData((byte)pEventCode);
Dictionary<byte, object> data = new Dictionary<byte, object>();
data[1] = (byte)pCode;
data[2] = pParms;
eventData.SetParameters(data);
var peers = MyGameServer.Peers;
foreach (var temp in peers)
{
temp.SendEvent(eventData, new SendParameters());
}
}
public virtual void OnSendAllNotMe(ClientPeer pPeer,EventCode pEventCode, ParamsCode pCode, object pParms, SendParameters sendParameters)
{
EventData eventData = new EventData((byte)pEventCode);
Dictionary<byte, object> data = new Dictionary<byte, object>();
data[1] = (byte)pCode;
data[2] = pParms;
eventData.SetParameters(data);
var peers = MyGameServer.Peers;
foreach (var temp in peers)
{
if (temp != pPeer)
{
temp.SendEvent(eventData, new SendParameters());
}
}
}
public virtual void OnAck(ClientPeer pPeer, OperationCode pReqCode, ParamsCode pCode, object pParms, SendParameters sendParameters)
{
MyGameServer.log.Info("OnAck pReqCode is :" + pReqCode + "ParamsCode is :" + pCode);
OperationResponse opRes = new OperationResponse((byte)pReqCode);
Dictionary<byte, object> data = new Dictionary<byte, object>();
data[1] = (byte)pCode;
data[2] = pParms;
opRes.SetParameters(data);
pPeer.SendOperationResponse(opRes, sendParameters);
}
}
}
7.账号注册模块:
using Common;
using Photon.SocketServer;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyPhServer
{
public class AccountLogin : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.Login; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
// MyGameServer.log.Info("收到客户端请求!!!Login");
string name = GetParamerers(pData, 1) as string;
string passWord = GetParamerers(pData, 2) as string;
UserManager.Instance.OnLogin(pPeer, name, passWord, (oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
});
}
}
public class AccountReg : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.Reg; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
//MyGameServer.log.Info("收到客户端 AccountReg 请求!!!");
string name = GetParamerers(pData, 1) as string;
string passWord = GetParamerers(pData, 2) as string;
UserManager.Instance.OnReg(name, passWord, (oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
});
}
}
}
8.聊天模块:
using Common;
using Photon.SocketServer;
using System.Collections.Generic;
namespace MyPhServer
{
public class ChatListReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.ChatList; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
MyGameServer.log.Info("收到客户端 ChatListReq 请求!!!");
ChatManager.Instance.OnChatList((oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
});
}
}
public class ChatReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.Chat; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
MyGameServer.log.Info("收到客户端 ChatReq 请求!!!");
string name = GetParamerers(pData, 1) as string;
string message = GetParamerers(pData, 2) as string;
ChatManager.Instance.OnChat(name, message, (oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
OnSendAllNotMe(pPeer, EventCode.ChatEvent, oCode, pObj, new SendParameters());
});
}
}
}
9.房间创建模块:
using Common;
using Photon.SocketServer;
using System.Collections.Generic;
namespace MyPhServer
{
public class RoomCreatBotReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.CreatBot; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
int botId = (int)GetParamerers(pData, 1);
RoomManager.Instance.CreatBot(playerId,botId);
SendAllInRoom(pPeer, EventCode.RoomCreatBot, ParamsCode.Success, pData, new SendParameters());
}
}
public class RoomSetCampReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.SetCamp; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
int campType = (int)GetParamerers(pData, 1);
RoomManager.Instance.RoomSetCamp(playerId, campType,(oCode, pObj) => {
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
SendAllInRoom(pPeer, EventCode.RoomEvent, oCode, pObj, new SendParameters());
});
}
}
public class RoomReadyReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.ReadyRoom; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
RoomManager.Instance.RoomReady(playerId, (oCode, pObj) =>{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
SenhdAllInRoomNotMe(pPeer, EventCode.RoomEvent, oCode, pObj, new SendParameters());
},(pIsAllReady, pObj) => {
if (pIsAllReady)
{
SendAllInRoom(pPeer, EventCode.RoomAllReady, ParamsCode.Success, pObj, new SendParameters());
}
});
}
}
public class RoomUnReadyReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.UnReadyRoom; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
RoomManager.Instance.RoomUnReady(playerId, (oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
SenhdAllInRoomNotMe(pPeer, EventCode.RoomEvent, oCode, pObj, new SendParameters());
});
}
}
public class RoomEnterReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.EnterRoom; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
RoomManager.Instance.EnterRoom(playerId, (oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
});
}
}
public class RoomListReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.RoomList; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
RoomManager.Instance.RoomList(pPeer, (oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
SenhdAllInRoomNotMe(pPeer, EventCode.RoomEvent, oCode, pObj, new SendParameters());
});
}
}
public class RoomCreatReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.RoomCreat; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
int count = (int)GetParamerers(pData, 1);
RoomManager.Instance.OnCreat(playerId, count, (oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
});
}
}
public class RoomJoinReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.JoinRoom; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
int roomId = (int)GetParamerers(pData, 1);
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
RoomManager.Instance.JoinRoom(playerId, roomId,(oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
});
}
}
public class RoomLeavlReq : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.LeavlRoom; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
int roomId = (int)GetParamerers(pData, 1);
var playerId = UserManager.Instance.GetPlayerIdByPeer(pPeer);
RoomManager.Instance.LeavlRoom(playerId, roomId,(oCode, pObj) =>
{
OnAck(pPeer, pCode, oCode, pObj, new SendParameters());
});
}
}
}
10.战斗中信息推送模块:
using Common;
using Photon.SocketServer;
using System;
using System.Collections.Generic;
namespace MyPhServer
{
public class BattleInfo : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.BattleInfo; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
SenhdAllInRoomNotMe(pPeer, EventCode.BattleInfo, ParamsCode.Success, pData, new SendParameters());
}
}
public class AllBattleInfo : ReqHandleBase
{
public override OperationCode OpCode { get { return OperationCode.AllBattleInfo; } }
public override void OnReq(ClientPeer pPeer, OperationCode pCode, Dictionary<byte, object> pData)
{
SendAllInRoom(pPeer, EventCode.AllBattleInfo, ParamsCode.Success, pData, new SendParameters());
}
}
}