标签:cep final next catch equal start == file类 zzu
本次主要用Java实现简单的游戏服务器事件通知,在游戏服中,事件通知是必不可少的一种游戏业务处理逻辑,可以基于观察者模式去编写,或则其他更好的方式。也可以用guava框架的事件通知框架,以下代码只是大概的实现思想,总体设计思路都大同小异;
1.Event注解
package ge;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Event {
public GameEventType value();
}
处理器接口
IGameEventHandler.Java
package ge;
public interface IGameEventHandler extends Runnable{
}
GameEventHadler.java(父类事件处理器实现类)
package ge;
public abstract class GameEventHadler implements IGameEventHandler {
/**
* 事件类型
*/
private GameEventType gameEventType;
/**
* 传递的参数
*/
private GameEventMsg gameEventMsg;
@Override
public void run() {
notice(gameEventType, gameEventMsg);
}
public abstract void notice(GameEventType gameEventType, GameEventMsg gameEventMsg);
/**
* 设置参数
*
* @param gameEventType
* @param gameEventMsg
* @return
*/
public GameEventHadler transmit(GameEventType gameEventType, GameEventMsg gameEventMsg) {
this.gameEventType = gameEventType;
this.gameEventMsg = gameEventMsg;
return this;
}
public GameEventType getGameEventType() {
return gameEventType;
}
public void setGameEventType(GameEventType gameEventType) {
this.gameEventType = gameEventType;
}
public GameEventMsg getGameEventMsg() {
return gameEventMsg;
}
public void setGameEventMsg(GameEventMsg gameEventMsg) {
this.gameEventMsg = gameEventMsg;
}
}
事件管理器
GameEventMgr。Java
package ge;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import ge.util.EventRegister;
public class GameEventMgr {
public static GameEventMgr observerMgr = new GameEventMgr();
public static final String EVENT_PACKGE = "ge.imp";
public static GameEventMgr getIns() {
return observerMgr;
}
private static final int MAX_THREAD_NUM = Runtime.getRuntime().availableProcessors() * 2;
/**
* 事件执行线程池
*/
private static ExecutorService executorService = Executors.newFixedThreadPool(MAX_THREAD_NUM);
/**
* 事件处理器容器
*/
public static Map gameEventHadlerMaps = new HashMap();
static {
// 注解注册
EventRegister.registeredByAnnotation();
// 代码对象注册
EventRegister.registeredByClassCode();
}
/**
* 事件通知
* @param gameEventType
* @param gameEventMsg
*/
public static void poolEvent(GameEventType gameEventType, GameEventMsg gameEventMsg) {
if (gameEventHadlerMaps.containsKey(gameEventType)) {
GameEventHadler gameEventHadler = gameEventHadlerMaps.get(gameEventType);
executorService.execute(gameEventHadler.transmit(gameEventType, gameEventMsg));
}
}
/**
* 优雅的关闭线程池子
*/
public static void shutDownExecutorService() {
if (executorService != null) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdown();
}
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
}
} catch (Exception e) {
executorService.shutdown();
Thread.currentThread().interrupt();
}
}
System.err.println("Thread pool shutdown:OK");
}
}
事件消息基类
GameEventMsg。Java
package ge;
/**
* 事件消息基类
* @author admin
*
*/
public abstract class GameEventMsg {
}
事件类型枚举类
package ge;
public enum GameEventType {
UP_LEVEL(1, "升级事件"),
VIP_UP_LEVEL(2, "VIP升级事件"),
RECHARGE(3, "充值事件"),
MONSTER_DIE(4,"怪物死亡"),
;
private int value;
private String des;
GameEventType(int value, String des) {
this.value = value;
this.des = des;
}
public String getDes() {
return des;
}
public int getValue() {
return value;
}
}
消息实体
package ge.event;
import ge.GameEventMsg;
public class MonsterDeath_GE extends GameEventMsg {
// 击杀者
private long killPlayerId;
// 怪物id
private int monsterId;
public long getKillPlayerId() {
return killPlayerId;
}
public void setKillPlayerId(long killPlayerId) {
this.killPlayerId = killPlayerId;
}
public int getMonsterId() {
return monsterId;
}
public void setMonsterId(int monsterId) {
this.monsterId = monsterId;
}
}
package ge.event;
import ge.GameEventMsg;
public class RechargeEvent_GE extends GameEventMsg{
/**
* 充值数量
*/
private int rechargeNum;
public int getRechargeNum() {
return rechargeNum;
}
public void setRechargeNum(int rechargeNum) {
this.rechargeNum = rechargeNum;
}
}
package ge.event;
import ge.GameEventMsg;
public class UpLevelEvent_GE extends GameEventMsg{
/**
* 等级
*/
private int level;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
package ge.event;
import ge.GameEventMsg;
public class VipLevelEvent_GE extends GameEventMsg{
/**
* VIP等级
*/
private int vipLevel;
public int getVipLevel() {
return vipLevel;
}
public void setVipLevel(int vipLevel) {
this.vipLevel = vipLevel;
}
}
通知处理器
package ge.imp;
import ge.GameEventHadler;
import ge.GameEventMsg;
import ge.GameEventType;
import ge.event.MonsterDeath_GE;
import ge.mgr.MonsterMgr;
public class MonsterDeathHandler extends GameEventHadler {
@Override
public void notice(GameEventType gameEventType, GameEventMsg gameEventMsg) {
MonsterDeath_GE MonsterDeath_GE = (MonsterDeath_GE) gameEventMsg;
MonsterMgr.getIns().monsterKillEvent(MonsterDeath_GE.getKillPlayerId(), MonsterDeath_GE.getMonsterId());
}
}
package ge.imp;
import ge.Event;
import ge.GameEventHadler;
import ge.GameEventMsg;
import ge.GameEventType;
import ge.mgr.RechargeMgr;
import observer.event.RechargeEvent_GE;
/**
* 接收事件触发后的业务处理
*
* @author admin
*
*/
@Event(GameEventType.RECHARGE)
public class RechargeEventHandler extends GameEventHadler {
@Override
public void notice(GameEventType gameEventType, GameEventMsg gameEventMsg) {
RechargeEvent_GE e = (RechargeEvent_GE) gameEventMsg;
RechargeMgr.getIns().rechargeEvent(e.getRechargeNum());
/**
* 通常相关业务处理:充值奖励,VIP充值经验增加等
*/
}
}
package ge.imp;
import ge.Event;
import ge.GameEventHadler;
import ge.GameEventMsg;
import ge.GameEventType;
import ge.mgr.LevelMgr;
import observer.event.UpLevelEvent_GE;
/**
* 接收事件触发后的业务处理
*
* @author admin
*
*/
@Event(GameEventType.UP_LEVEL)
public class UpLevelEventHandler extends GameEventHadler {
@Override
public void notice(GameEventType gameEventType, GameEventMsg gameEventMsg) {
UpLevelEvent_GE e = (UpLevelEvent_GE) gameEventMsg;
LevelMgr.getIns().uplevelEvent(e.getLevel());
/**
* 通常相关业务处理:玩家战力,系统开放,等级礼包,等级排行等相关
*/
}
}
package ge.imp;
import ge.Event;
import ge.GameEventHadler;
import ge.GameEventMsg;
import ge.GameEventType;
import ge.mgr.VipMgr;
import observer.event.VipLevelEvent_GE;
/**
* 接收事件触发后的业务处理
*
* @author admin
*
*/
@Event(GameEventType.VIP_UP_LEVEL)
public class VipUpLevelEventHandler extends GameEventHadler {
@Override
public void notice(GameEventType gameEventType, GameEventMsg gameEventMsg) {
VipLevelEvent_GE e = (VipLevelEvent_GE) gameEventMsg;
VipMgr.getIns().vipLevelEvent(e.getVipLevel());
/**
* 通常相关业务处理:VIP特权,奖励,系统开放相关等
*/
}
}
模拟业务管理器调用
package ge.mgr;
/**
* 业务类
* @author admin
*
*/
public class LevelMgr {
private static LevelMgr levelMgr=new LevelMgr();
public static LevelMgr getIns() {
return levelMgr;
}
public void uplevelEvent(int level) {
System.err.println("升级到:" + level);
}
}
package ge.mgr;
/**
* 业务类
*
* @author admin
*
*/
public class MonsterMgr {
private static MonsterMgr monsterMgr = new MonsterMgr();
public static MonsterMgr getIns() {
return monsterMgr;
}
public void monsterKillEvent(long killPlayer, int monsterId) {
System.err.println("击杀者ID:" + killPlayer + ":怪物id:" + monsterId);
}
}
package ge.mgr;
/**
* 业务类
*
* @author admin
*
*/
public class RechargeMgr {
private static RechargeMgr rechargeMgr = new RechargeMgr();
public static RechargeMgr getIns() {
return rechargeMgr;
}
public void rechargeEvent(int rechargeNum) {
System.err.println("充值了" + rechargeNum);
}
}
package ge.mgr;
public class VipMgr {
/**
* 业务类
*/
private static VipMgr vipMgr=new VipMgr();
public static VipMgr getIns() {
return vipMgr;
}
public void vipLevelEvent(int vipLevel) {
System.err.println("VIP升级到:" + vipLevel);
}
}
工具类
package ge.util;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
public class ClazzUtils {
/**
* 从包package中获取所有的Class
*
* @param pack
* @return
*/
public static Set> getClasses(String pack) {
Set> classes = new LinkedHashSet>();
boolean recursive = true;
String packageName = pack;
String packageDirName = packageName.replace(‘.‘, ‘/‘);
Enumeration dirs;
try {
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
while (dirs.hasMoreElements()) {
URL url = dirs.nextElement();
String protocol = url.getProtocol();
if ("file".equals(protocol)) {
System.err.println("file类型的扫描");
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}
/**
* 以文件的形式来获取包下的所有Class
*
* @param packageName
* @param packagePath
* @param recursive
* @param classes
*/
public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive,
Set> classes) {
File dir = new File(packagePath);
if (!dir.exists() || !dir.isDirectory()) {
return;
}
File[] dirfiles = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
}
});
for (File file : dirfiles) {
if (file.isDirectory()) {
findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive,
classes);
} else {
String className = file.getName().substring(0, file.getName().length() - 6);
try {
classes.add(
Thread.currentThread().getContextClassLoader().loadClass(packageName + ‘.‘ + className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Set> clazz = getClasses("observer.imp");
clazz.forEach(s -> {
System.err.println(s);
});
}
}
事件处理器注册类
package ge.util;
import java.util.Set;
import ge.Event;
import ge.GameEventHadler;
import ge.GameEventMgr;
import ge.GameEventType;
import ge.imp.MonsterDeathHandler;
import observer.imp.RechargeEventHandler;
import observer.imp.UpLevelEventHandler;
import observer.imp.VipUpLevelEventHandler;
public class EventRegister {
/**
* 代码:注册事件处理器[注册方式1]
*/
public static void registeredByClassCode() {
registered(GameEventType.UP_LEVEL, new UpLevelEventHandler());
registered(GameEventType.RECHARGE, new RechargeEventHandler());
registered(GameEventType.VIP_UP_LEVEL, new VipUpLevelEventHandler());
registered(GameEventType.MONSTER_DIE, new MonsterDeathHandler());
}
/**
* 注册:如果存在就不再进行重复注册
*
* @param gameEventType
* @param gameEventHadler
*/
public static void registered(GameEventType gameEventType, GameEventHadler gameEventHadler) {
GameEventMgr.gameEventHadlerMaps.computeIfAbsent(gameEventType, s -> {
return gameEventHadler;
});
}
/**
* 通过扫描指定包名进行注册[注册方式2]
*/
public static void registeredByAnnotation() {
Set> clazzs = ClazzUtils.getClasses(GameEventMgr.EVENT_PACKGE);
if (clazzs == null||clazzs.isEmpty()) {
System.err.println("无可注册的事件处理器类");
return;
}
for (Class> clazz : clazzs) {
if (!clazz.isAnnotationPresent(Event.class)) {
continue;
}
Event event = clazz.getAnnotation(Event.class);
if (event == null) {
continue;
}
GameEventType gameEventType = event.value();
try {
GameEventMgr.gameEventHadlerMaps.put(gameEventType, (GameEventHadler) clazz.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
测试类
package ge;
import java.util.Scanner;
import ge.event.MonsterDeath_GE;
import observer.event.RechargeEvent_GE;
import observer.event.UpLevelEvent_GE;
import observer.event.VipLevelEvent_GE;
public class GameEventTest {
@SuppressWarnings("static-access")
/**
* 测试
*
* @param args
*/
public static void main(String[] args) throws InterruptedException {
/**
* 添加守护线程:在jvm关闭前关闭线程池:一般用在服务器关闭前的操作{数据持久,线程池关闭等等...}
*/
Runtime.getRuntime().addShutdownHook(new Thread(() -> GameEventMgr.shutDownExecutorService()));
/**
* 模拟关闭程序命令操作
*/
new Thread(() -> closeSystemThread()).start();
/**
* 模拟玩家升级
*/
UpLevelEvent_GE upLevelEvent_GE = new UpLevelEvent_GE();
upLevelEvent_GE.setLevel(1000);
GameEventMgr.getIns().poolEvent(GameEventType.UP_LEVEL, upLevelEvent_GE);
/**
* 模拟vip升级
*/
VipLevelEvent_GE vipLevelEvent_GE = new VipLevelEvent_GE();
vipLevelEvent_GE.setVipLevel(12);
GameEventMgr.getIns().poolEvent(GameEventType.VIP_UP_LEVEL, vipLevelEvent_GE);
/**
* 模拟充值
*/
RechargeEvent_GE rechargeEvent_GE = new RechargeEvent_GE();
rechargeEvent_GE.setRechargeNum(500);
GameEventMgr.getIns().poolEvent(GameEventType.RECHARGE, rechargeEvent_GE);
/**
* 模拟怪物击杀
*/
MonsterDeath_GE monsterDeath_GE = new MonsterDeath_GE();
monsterDeath_GE.setKillPlayerId(1000200088);
monsterDeath_GE.setMonsterId(100008);
GameEventMgr.getIns().poolEvent(GameEventType.MONSTER_DIE, monsterDeath_GE);
}
/**
* 关闭程序
*/
@SuppressWarnings("resource")
public static void closeSystemThread() {
Scanner scanner = new Scanner(System.in);
if (scanner.next().equals("close"))
System.exit(0);
}
}
Java游戏服(简单事件通知实现)
标签:cep final next catch equal start == file类 zzu
原文地址:https://www.cnblogs.com/mature1021/p/13354242.html