diff --git a/serverlogic/src/main/java/com/ljsd/jieling/globals/Global.java b/serverlogic/src/main/java/com/ljsd/jieling/globals/Global.java index f56962015..a572efc16 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/globals/Global.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/globals/Global.java @@ -37,4 +37,9 @@ public interface Global { int MONSTER_1 = 0; int MONSTER_2 = 1; int MONSTER_3 = 2; + + + //返回状态 + int USER_NO_EXIT_STATE = 10000; // 玩家不存在 + int NO_FIND_ONESELF_STATE = 10001; // 不能查找自己 } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/friend/RefreshFriendStateRequestHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/friend/RefreshFriendStateRequestHandler.java new file mode 100644 index 000000000..46affbd8a --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/friend/RefreshFriendStateRequestHandler.java @@ -0,0 +1,25 @@ +package com.ljsd.jieling.handler.friend; + +import com.ljsd.jieling.handler.BaseHandler; +import com.ljsd.jieling.logic.friend.FriendLogic; +import com.ljsd.jieling.netty.cocdex.PacketNetData; +import com.ljsd.jieling.network.session.ISession; +import com.ljsd.jieling.protocols.MessageTypeProto; +import com.ljsd.jieling.protocols.PlayerInfoProto; +import org.springframework.stereotype.Component; + +import java.util.List; + + +@Component +public class RefreshFriendStateRequestHandler extends BaseHandler { + @Override + public MessageTypeProto.MessageType getMessageCode() { + return MessageTypeProto.MessageType.REFRESH_FRIEND_STATE_REQEUST; + } + + @Override + public void process(ISession iSession, PacketNetData netData) throws Exception { + FriendLogic.getInstance().refreshFirendState(iSession); + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/map/MapManager.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/map/MapManager.java index d385694f7..c32113e0b 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/handler/map/MapManager.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/map/MapManager.java @@ -219,6 +219,7 @@ public class MapManager extends MongoBase { if (addValue != 0) { int curEnergy = MathUtils.setBetweenWithMax(itemNum + addValue, 0, SGameSetting.getGameSetting().getInitialEnergy()); item.setItemNum(curEnergy > playerInfoManager.getMaxStamina() ? playerInfoManager.getMaxStamina() : curEnergy); + System.out.println("增加之前的==============================="+itemNum + "增加的数量============"+addValue +"总数========="+item.getItemNum()); setLastUpdateEnergyTime(item, updateTime, lastUpdateEnergyTime); } } else { diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomCancelMatchRequestHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomCancelMatchRequestHandler.java new file mode 100644 index 000000000..694daa960 --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomCancelMatchRequestHandler.java @@ -0,0 +1,24 @@ +package com.ljsd.jieling.handler.room; + +import com.ljsd.jieling.handler.BaseHandler; +import com.ljsd.jieling.logic.room.RoomManager; +import com.ljsd.jieling.netty.cocdex.PacketNetData; +import com.ljsd.jieling.network.session.ISession; +import com.ljsd.jieling.protocols.MessageTypeProto; +import com.ljsd.jieling.protocols.RoomProto; +import org.springframework.stereotype.Component; + +@Component +public class RoomCancelMatchRequestHandler extends BaseHandler{ + @Override + public MessageTypeProto.MessageType getMessageCode() { + return MessageTypeProto.MessageType.ROOM_CANCEL_MATCH_REQUEST; + } + + @Override + public void process(ISession iSession, PacketNetData netData) throws Exception { + byte[] message = netData.parseClientProtoNetData(); + RoomProto.RoomCancelMatchRequest request = RoomProto.RoomCancelMatchRequest.parseFrom(message); + RoomManager.removePlayer(iSession, request, MessageTypeProto.MessageType.ROOM_CANCEL_MATCH_RESPONSE_VALUE); + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomGameStartRequestHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomGameStartRequestHandler.java new file mode 100644 index 000000000..f30407fb0 --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomGameStartRequestHandler.java @@ -0,0 +1,25 @@ +package com.ljsd.jieling.handler.room; + +import com.ljsd.jieling.handler.BaseHandler; +import com.ljsd.jieling.logic.room.RoomManager; +import com.ljsd.jieling.netty.cocdex.PacketNetData; +import com.ljsd.jieling.network.session.ISession; +import com.ljsd.jieling.protocols.MessageTypeProto; +import com.ljsd.jieling.protocols.RoomFightProto; +import com.ljsd.jieling.protocols.RoomProto; +import org.springframework.stereotype.Component; + +@Component +public class RoomGameStartRequestHandler extends BaseHandler{ + @Override + public MessageTypeProto.MessageType getMessageCode() { + return MessageTypeProto.MessageType.ROOM_GAME_START_REQUEST; + } + + @Override + public void process(ISession iSession, PacketNetData netData) throws Exception { + byte[] message = netData.parseClientProtoNetData(); + RoomFightProto.RoomGameStartRequest request = RoomFightProto.RoomGameStartRequest.parseFrom(message); + RoomManager.startGameRequset(iSession, request, MessageTypeProto.MessageType.ROOM_GAME_START_RESPONSE_VALUE); + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomMatchRequestHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomMatchRequestHandler.java new file mode 100644 index 000000000..480d37a77 --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomMatchRequestHandler.java @@ -0,0 +1,26 @@ +package com.ljsd.jieling.handler.room; + +import com.ljsd.jieling.handler.BaseHandler; +import com.ljsd.jieling.handler.map.MapLogic; +import com.ljsd.jieling.logic.room.RoomManager; +import com.ljsd.jieling.netty.cocdex.PacketNetData; +import com.ljsd.jieling.network.session.ISession; +import com.ljsd.jieling.protocols.MapInfoProto; +import com.ljsd.jieling.protocols.MessageTypeProto; +import com.ljsd.jieling.protocols.RoomProto; +import org.springframework.stereotype.Component; + +@Component +public class RoomMatchRequestHandler extends BaseHandler{ + @Override + public MessageTypeProto.MessageType getMessageCode() { + return MessageTypeProto.MessageType.ROOM_MATCH_REQUEST; + } + + @Override + public void process(ISession iSession, PacketNetData netData) throws Exception { + byte[] message = netData.parseClientProtoNetData(); + RoomProto.RoomMatchRequest request = RoomProto.RoomMatchRequest.parseFrom(message); + RoomManager.addPlayer(iSession, request, MessageTypeProto.MessageType.ROOM_MATCH_RESPONSE_VALUE); + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomStartGameReadyRequestHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomStartGameReadyRequestHandler.java new file mode 100644 index 000000000..398136877 --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomStartGameReadyRequestHandler.java @@ -0,0 +1,24 @@ +package com.ljsd.jieling.handler.room; + +import com.ljsd.jieling.handler.BaseHandler; +import com.ljsd.jieling.logic.room.RoomManager; +import com.ljsd.jieling.netty.cocdex.PacketNetData; +import com.ljsd.jieling.network.session.ISession; +import com.ljsd.jieling.protocols.MessageTypeProto; +import com.ljsd.jieling.protocols.RoomProto; +import org.springframework.stereotype.Component; + +@Component +public class RoomStartGameReadyRequestHandler extends BaseHandler{ + @Override + public MessageTypeProto.MessageType getMessageCode() { + return MessageTypeProto.MessageType.ROOM_START_GAME_READY_REQUEST; + } + + @Override + public void process(ISession iSession, PacketNetData netData) throws Exception { + byte[] message = netData.parseClientProtoNetData(); + RoomProto.RoomStartGameReadyRequest request = RoomProto.RoomStartGameReadyRequest.parseFrom(message); + RoomManager.ready(iSession, request, MessageTypeProto.MessageType.ROOM_START_GAME_READY_RESPONSE_VALUE); + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomSyncMyselfMoveRequestHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomSyncMyselfMoveRequestHandler.java new file mode 100644 index 000000000..1977ac0bb --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/room/RoomSyncMyselfMoveRequestHandler.java @@ -0,0 +1,25 @@ +package com.ljsd.jieling.handler.room; + +import com.ljsd.jieling.handler.BaseHandler; +import com.ljsd.jieling.logic.room.RoomManager; +import com.ljsd.jieling.netty.cocdex.PacketNetData; +import com.ljsd.jieling.network.session.ISession; +import com.ljsd.jieling.protocols.MessageTypeProto; +import com.ljsd.jieling.protocols.RoomFightProto; +import com.ljsd.jieling.protocols.RoomProto; +import org.springframework.stereotype.Component; + +@Component +public class RoomSyncMyselfMoveRequestHandler extends BaseHandler{ + @Override + public MessageTypeProto.MessageType getMessageCode() { + return MessageTypeProto.MessageType.ROOM_SYNC_MYSELF_MOVE_REQUEST; + } + + @Override + public void process(ISession iSession, PacketNetData netData) throws Exception { + byte[] message = netData.parseClientProtoNetData(); + RoomFightProto.RoomSyncMyselfMoveRequest request = RoomFightProto.RoomSyncMyselfMoveRequest.parseFrom(message); + RoomManager.roomSyncMyselfMoveRequest(iSession, request, MessageTypeProto.MessageType.ROOM_SYNC_MYSELF_MOVE_RESPONSE_VALUE); + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/RoomInfo.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/RoomInfo.java new file mode 100644 index 000000000..b2f3e197d --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/RoomInfo.java @@ -0,0 +1,22 @@ +package com.ljsd.jieling.logic.dao; + +public class RoomInfo { + private boolean matching; + private int roomId; + + public boolean isMatching() { + return matching; + } + + public void setMatching(boolean matching) { + this.matching = matching; + } + + public int getRoomId() { + return roomId; + } + + public void setRoomId(int roomId) { + this.roomId = roomId; + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java index ece685534..0a02ba846 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java @@ -114,6 +114,10 @@ public class UserManager { return user; } + public static User getUserInMem(int uid) { + User user = userMap.get(uid); + return user; + } public static void removeUser(int uid) { userMap.remove(uid); } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java index 84b6ec311..668a206b9 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/User.java @@ -45,6 +45,8 @@ public class User { private UserMissionManager userMissionManager; private FriendManager friendManager; + private RoomInfo roomInfo; + //构造函数必须要声明,否则从mongodb读出来反编译成类不通过 public User(){ } @@ -197,4 +199,11 @@ public class User { public FriendManager getFriendManager() { return friendManager; } + + public RoomInfo getRoomInfo() { + if(roomInfo == null){ + roomInfo = new RoomInfo(); + } + return roomInfo; + } } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/friend/FriendLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/friend/FriendLogic.java index 46e4289bc..04781ba18 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/friend/FriendLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/friend/FriendLogic.java @@ -4,6 +4,7 @@ import com.ljsd.jieling.db.mongo.MongoUtil; import com.ljsd.jieling.db.redis.RedisKey; import com.ljsd.jieling.db.redis.RedisUtil; import com.ljsd.jieling.globals.BIReason; +import com.ljsd.jieling.globals.Global; import com.ljsd.jieling.globals.GlobalItemType; import com.ljsd.jieling.logic.OnlineUserManager; import com.ljsd.jieling.logic.dao.FriendManager; @@ -34,7 +35,27 @@ public class FriendLogic { return FriendLogic.Instance.instance; } - + /** + * 刷新好友状态 + * @param iSession + */ + public void refreshFirendState(ISession iSession) throws Exception { + int uid = iSession.getUid(); + User user = UserManager.getUser(uid); + FriendManager friendManager = user.getFriendManager(); + List friends = friendManager.getFriends(); + List onlineList = new CopyOnWriteArrayList<>(); + for (Integer friendId :friends){ + if(!OnlineUserManager.checkUidOnline(uid)){ + continue; + } + onlineList.add(friendId); + } + PlayerInfoProto.RefreshFriendStateResponse refreshFriendStateResponse = PlayerInfoProto.RefreshFriendStateResponse + .newBuilder().addAllFriendIds(onlineList) + .build(); + MessageUtil.sendMessage(iSession, 1, MessageTypeProto.MessageType.REFRESH_FRIEND_STATE_RESPONSE_VALUE, refreshFriendStateResponse, true); + } /** * 获取好友信息 */ @@ -168,7 +189,7 @@ public class FriendLogic { applyFriends.remove(0); } friendManager.addApplyFriend(uid); - sendFriendInfoIndication(uid,1); + sendFriendInfoIndication(uid,inviteUid,1); } MessageUtil.sendMessage(iSession, 1, msgId, null, true); } @@ -177,16 +198,25 @@ public class FriendLogic { * 在线好友申请推送 * @param inviteUid */ - private void sendFriendInfoIndication(int inviteUid,int type) throws Exception { + private void sendFriendInfoIndication(int uid,int inviteUid,int type) throws Exception { boolean isOnline = OnlineUserManager.checkUidOnline(inviteUid); - if (isOnline){ + if (isOnline) { ISession session = OnlineUserManager.getSessionByUid(inviteUid); PlayerInfoProto.sendFriendInfoIndication.Builder sendFriendInfoIndication = PlayerInfoProto.sendFriendInfoIndication.newBuilder(); - sendFriendInfoIndication .setType(type); - if (type == 1){ - sendFriendInfoIndication .setFriends(CBean2Proto.getFriendInfo(inviteUid,null)); - } - MessageUtil.sendIndicationMessage(session, 1, MessageTypeProto.MessageType.SEND_FRIEND_INFO_INDICATION_VALUE, sendFriendInfoIndication.build(), true); + sendFriendInfoIndication.setType(type); + sendFriendInfoIndication.setFriends(CBean2Proto.getFriendInfo(uid, null)); + MessageUtil.sendIndicationMessage(session, 1, MessageTypeProto.MessageType.SEND_FRIEND_INFO_INDICATION_VALUE, sendFriendInfoIndication.build(), true); + } + } + //t推送赠送体力状态 + private void sendFriendStatedication(int uid ,int inviteUid,int type) { + boolean isOnline = OnlineUserManager.checkUidOnline(inviteUid); + if (isOnline) { + ISession session = OnlineUserManager.getSessionByUid(inviteUid); + PlayerInfoProto.SendFriendStateIndication.Builder sendFriendStateIndication = PlayerInfoProto.SendFriendStateIndication.newBuilder(); + sendFriendStateIndication.setType(type); + sendFriendStateIndication.setFriendId(uid); + MessageUtil.sendIndicationMessage(session, 1, MessageTypeProto.MessageType.SEND_FRIEND_STATE_INDICATION_VALUE, sendFriendStateIndication.build(), true); } } @@ -233,7 +263,7 @@ public class FriendLogic { friendfriendManager.addFriendId(uid); initFriendGriveAndRreward(friendId, uid, friendManager, friendfriendManager); - sendFriendInfoIndication(friendId,2); + sendFriendInfoIndication(uid,friendId,2); break; case 2://拒绝 applyFriends = friendManager.getApplyFriends(); @@ -272,7 +302,7 @@ public class FriendLogic { friendfriendManager.addFriendId(uid); friendManager.addFriendId(applyfriendId); initFriendGriveAndRreward(applyfriendId, uid, friendManager, friendfriendManager); - sendFriendInfoIndication(applyfriendId,2); + sendFriendInfoIndication(uid,applyfriendId,2); } } @@ -302,14 +332,14 @@ public class FriendLogic { User friendUser = UserManager.getUser(friendId); FriendManager friendManager1 = friendUser.getFriendManager(); delFriendInfo(friendId, uid, friendManager, friendManager1); - sendFriendInfoIndication(friendId,3); + sendFriendStatedication(uid,friendId,1); MessageUtil.sendMessage(iSession, 1, msgId, null, true); } //删除好友清除赠送领取体力信息 private void delFriendInfo(int friendId, int uid, FriendManager friendManager, FriendManager friendManager1) { friendManager1.delFriends(uid); - friendManager1.delGiveMap(friendId); - friendManager1.delHaveReward(friendId); + friendManager1.delGiveMap(uid); + friendManager1.delHaveReward(uid); friendManager.delFriends(friendId); friendManager.delGiveMap(friendId); friendManager.delHaveReward(friendId); @@ -346,7 +376,7 @@ public class FriendLogic { } friendManager.updateGiveMap(friendId,1); friendManager1.updateHaveRewardMap(uid,1); - sendFriendInfoIndication(friendId,4); + sendFriendStatedication(uid,friendId,2); }else{ //赠送全部好友 for (Integer friendUserId : friends) { if (giveMap.get(friendUserId) == 1) { @@ -360,7 +390,7 @@ public class FriendLogic { } friendManager.updateGiveMap(friendUserId,1); friendManager1.updateHaveRewardMap(uid,1); - sendFriendInfoIndication(friendUserId,4); + sendFriendStatedication(uid,friendUserId,2); } } MessageUtil.sendMessage(iSession, 1, msgId, null, true); @@ -426,17 +456,17 @@ public class FriendLogic { List friends = friendManager.getFriends(); boolean result = ShieldedWordUtils.checkName( name); if (!result) { - MessageUtil.sendErrorResponse(iSession, 0, msgId, ""); + MessageUtil.sendErrorResponse(iSession, 0, msgId, "名字不合法"); return; } if (playerInfoManager.getNickName().equals(name)){ - MessageUtil.sendErrorResponse(iSession, 0, msgId, "不可以查找自己"); + MessageUtil.sendErrorCode(iSession, Global.NO_FIND_ONESELF_STATE, "不能查找自己"); return; } String key = RedisKey.getKey(RedisKey.C_User_Name_Key, name, false); Object friend = RedisUtil.getInstence().get(key); if (friend == null){ - MessageUtil.sendErrorResponse(iSession, 0, msgId, "该玩家不存在"); + MessageUtil.sendErrorCode(iSession, Global.USER_NO_EXIT_STATE, "玩家不存在"); return; } int type = 1; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/room/Room.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/room/Room.java new file mode 100644 index 000000000..4c7d0bb97 --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/room/Room.java @@ -0,0 +1,195 @@ +package com.ljsd.jieling.logic.room; + +import com.ljsd.jieling.handler.map.TemporaryItems; +import com.ljsd.jieling.logic.dao.UserManager; +import com.ljsd.jieling.logic.dao.root.User; +import com.ljsd.jieling.network.session.ISession; +import com.ljsd.jieling.protocols.CommonProto; +import com.ljsd.jieling.protocols.FightInfoProto; +import com.ljsd.jieling.protocols.RoomFightProto; +import com.ljsd.jieling.protocols.RoomProto; +import com.ljsd.jieling.util.MessageUtil; + +import java.util.ArrayList; +import java.util.List; + +public class Room { + private int roomId; + private RoomPlayerInfo[] roomPlayerInfos; + private long gameStartTimestamp; //游戏开始时间戳 + //private static long MAX_GAME_LENGTH = 2*60*1000; //2分钟 + private static int MAX_GAME_LENGTH = 15*1000; //15秒测试使用 + + private int type; //房间类型 + private int mapId; + + public Room(int roomId, int type, int[] playerArray) + { + this.roomId = roomId; + this.type = type; + roomPlayerInfos = new RoomPlayerInfo[playerArray.length]; + for(int i=0; i= MAX_GAME_LENGTH){ + //游戏到时结束 + endGame(null); + return true; + } + //其他逻辑处理,例如资源点回复 + return false; + } + + public void startGame(){ + gameStartTimestamp = System.currentTimeMillis(); + for(int i=0; i matchingPlayerList = new ArrayList(); + private static Object lock; //线程安全锁 + + private static int PLAYER_NUMBER_IN_ROOM = 3; //单个房间的最大数量 + + public static int SIMPLEST_MATCH_RULE = 0; + + //房间自增ID + //private static AtomicInteger incrRoomId = new AtomicInteger(0); + private static int incrRoomId = 1; //函数都加了synchronized,因此不需要原子类 + + //Key房间ID + private static Map roomMap = new HashMap<>(); + private static int MAX_ROOM_NUMBER = 100; + + //以下的所有public方法必须加synchronized + + //有用户加入时,同时做匹配 + //matchRule 匹配规则 + public static synchronized void addPlayer(ISession iSession, RoomProto.RoomMatchRequest request, int responseMsgId) throws Exception { + User user = UserManager.getUserInMem(iSession.getUid()); + //if(roomNumber >= MAX_ROOM_NUMBER){ + if(roomMap.size() >= MAX_ROOM_NUMBER){ + //没有剩余房间 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "没有剩余房间"); + return; + } + if(user.getRoomInfo().isMatching()){ + //已经在匹配队列中了 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "已经在匹配队列中了"); + return; + } + if(user.getRoomInfo().getRoomId() != -1){ + //已经在房间中了 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "已经在房间中了"); + return; + } + user.getRoomInfo().setMatching(true); + matchingPlayerList.add(user.getId()); + + //默认执行最简匹配规则 + int[] playerArray = simplestMatch(); + MessageUtil.sendRoomMatchResponse(iSession, responseMsgId, request.getType(), true); + if(playerArray == null){ + return; + } + + createRoom(iSession, request, playerArray); + } + public static synchronized void removePlayer(ISession iSession, RoomProto.RoomCancelMatchRequest request, int responseMsgId) throws Exception { + User user = UserManager.getUserInMem(iSession.getUid()); + if(user.getRoomInfo().isMatching()){ + //使用isMatching,防止频繁遍历matchingPlayerList + user.getRoomInfo().setMatching(false); + matchingPlayerList.remove((Object)user.getId()); + MessageUtil.sendRoomCancelMatchResponse(iSession, responseMsgId, request.getType(), true); + return; + } + if(user.getRoomInfo().getRoomId() != -1){ + MessageUtil.sendRoomCancelMatchResponse(iSession, responseMsgId, request.getType(), true); + Room room = getRoomById(user.getRoomInfo().getRoomId()); + if(room.removeUserIsEndGame(request, user)){ + //游戏结束,移除房间 + roomMap.remove(room.getRoomId()); + } + user.getRoomInfo().setRoomId(-1); + return; + } + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "未再匹配或房间中"); + } + + private static int[] simplestMatch() { + if(matchingPlayerList.size() >= PLAYER_NUMBER_IN_ROOM){ + int[] playerArray = new int[PLAYER_NUMBER_IN_ROOM]; + for(int i=0; i> entries = roomMap.entrySet().iterator(); + while(entries.hasNext()){ + Map.Entry entry = entries.next(); + Room room = entry.getValue(); + if(room.timerRunIsEndGame(timestamp)){ + //当前游戏,技术删除房间 + entries.remove(); + } + } + } + + public static synchronized void ready(ISession iSession, RoomProto.RoomStartGameReadyRequest request, int responseMsgId) throws Exception { + User user = UserManager.getUserInMem(iSession.getUid()); + int roomId = user.getRoomInfo().getRoomId(); + if(roomId == -1){ + //没有在房间中 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "没有在房间中"); + return; + } + + Room room = getRoomById(user.getRoomInfo().getRoomId()); + if(room == null){ + //房间已经销毁,如果走到这一步,说明其他地方有错了 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "房间已经销毁"); + return; + } + + MessageUtil.sendRoomStartGameReadyResponse(iSession, responseMsgId, room.getType()); + room.ready(user.getId()); + } + //测试使用 + public static List getMatchingPlayerList() + { + return matchingPlayerList; + } + + //客户端发起请求,获取开始游戏时的初始数据 + public static synchronized void startGameRequset(ISession iSession, RoomFightProto.RoomGameStartRequest request, int responseMsgId) throws Exception { + User user = UserManager.getUserInMem(iSession.getUid()); + int roomId = user.getRoomInfo().getRoomId(); + if(roomId == -1){ + //没有在房间中 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "没有在房间中"); + return; + } + + Room room = getRoomById(user.getRoomInfo().getRoomId()); + if(room == null){ + //房间已经销毁,如果走到这一步,说明其他地方有错了 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "房间已经销毁"); + return; + } + + room.startGameRequset(iSession, responseMsgId, request); + } + + //客户端发起请求,获取开始游戏时的初始数据 + public static synchronized void roomSyncMyselfMoveRequest(ISession iSession, RoomFightProto.RoomSyncMyselfMoveRequest request, int responseMsgId) throws Exception { + User user = UserManager.getUserInMem(iSession.getUid()); + int roomId = user.getRoomInfo().getRoomId(); + if(roomId == -1){ + //没有在房间中 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "没有在房间中"); + return; + } + + Room room = getRoomById(user.getRoomInfo().getRoomId()); + if(room == null){ + //房间已经销毁,如果走到这一步,说明其他地方有错了 + MessageUtil.sendErrorResponse(iSession, 0, responseMsgId, "房间已经销毁"); + return; + } + + MessageUtil.sendRoomSyncMyselfMoveResponse(iSession, responseMsgId, request.getClientTimestamp()); + + room.roomSyncMyselfMove(iSession, request, responseMsgId); + } + //测试使用 + public static Map getRoomMap() + { + return roomMap; + } +} + diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/room/RoomPlayerInfo.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/room/RoomPlayerInfo.java new file mode 100644 index 000000000..15d0bdfa7 --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/room/RoomPlayerInfo.java @@ -0,0 +1,90 @@ +package com.ljsd.jieling.logic.room; + +import com.ljsd.jieling.protocols.RoomFightProto; +import com.ljsd.jieling.util.MapPoint; + +import java.util.ArrayList; +import java.util.List; + +public class RoomPlayerInfo { + private int uid; + + public static final int UNREADY_STATE = 0; //还未准备 + public static final int READYED_STATE = 1; //已准备 + public static final int GAMING_STATE = 2; //游戏中 + public static final int OFFLINE_STATE = 3; //掉线了 + private int state = UNREADY_STATE; //见上面的定义 + private int curPos; + private long preMoveTimestamp; //上次移动时间 + private int speed; //移动速度 + private List path; //根据目标点计算出来的移动路径 + + public RoomPlayerInfo(int uid) { + this.uid = uid; + state = UNREADY_STATE; + } + + //用户移动到新位置, 返回下一个点的坐标,用户展示客户端的转向,及模拟移动 + public boolean move(List path){ + int nextXY = path.get(0); //移动时的下一个点 + if(MapPoint.getX(curPos) == MapPoint.getX(nextXY)){ + if(MapPoint.getY(curPos) != MapPoint.getY(nextXY) + 1 || MapPoint.getY(curPos) != MapPoint.getY(nextXY) -1){ + //下一个点不是相邻的格子,作弊了 + return false; + } + } + if(MapPoint.getY(curPos) == MapPoint.getY(nextXY)){ + if(MapPoint.getX(curPos) != MapPoint.getX(nextXY) + 1 || MapPoint.getX(curPos) != MapPoint.getX(nextXY) -1){ + //下一个点不是相邻的格子,作弊了 + return false; + } + } + + this.path = path; + return true; + } + + //服务器模拟移动,如果前端模拟,则不需要服务气端调用这个函数,服务器端在事件触发的时候做校验即可 + //如果位置发生变化,则返回新的当前点 + public int move(long timestamp){ + if(path.size() <= 0){ + return -1; + } + int nextPoint = path.get(0); + int moveDistance = (int)((timestamp - preMoveTimestamp)*speed); + if(moveDistance < 1){ + //格子没有发生变化 + return -1; + } + for(int i=0; i 0){ + Thread.sleep(sleepTime); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void run() { + while(true){ + hotfixRun(); + } + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java b/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java index 41699dd8d..872a5c875 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java @@ -3,6 +3,7 @@ package com.ljsd.jieling.util; import com.ljsd.jieling.config.SMonsterConfig; import com.ljsd.jieling.handler.map.MapManager; import com.ljsd.jieling.handler.map.TemporaryItems; +import com.ljsd.jieling.logic.OnlineUserManager; import com.ljsd.jieling.logic.dao.*; import com.ljsd.jieling.logic.dao.root.User; import com.ljsd.jieling.protocols.ChatProto; @@ -267,7 +268,11 @@ public class CBean2Proto { friend.setId(user.getId()); friend.setName(playerInfoManager.getNickName()); friend.setLv(playerInfoManager.getLevel()); - friend.setOffLineTime(playerInfoManager.getOffLineTime()); + long isOnline = 0; + if (!OnlineUserManager.checkUidOnline(friendId)){ + isOnline = playerInfoManager.getOffLineTime(); + } + friend.setOffLineTime(isOnline); friend.setHaveReward(haveReward); friend.setIsGive(isGrive); friend.setHead(playerInfoManager.getHead()); diff --git a/serverlogic/src/main/java/com/ljsd/jieling/util/MapPoint.java b/serverlogic/src/main/java/com/ljsd/jieling/util/MapPoint.java new file mode 100644 index 000000000..1761bbf57 --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/util/MapPoint.java @@ -0,0 +1,64 @@ +package com.ljsd.jieling.util; + +public class MapPoint { + private int x; + private int y; + + public MapPoint(){ + + } + public MapPoint(int x, int y){ + this.x = x; + this.y = y; + } + + public static int getX(int xy){ + return xy&0xff; + } + public static int getY(int xy){ + return xy&0xff00>>8; + } + public MapPoint(int xy){ + setPoint(xy); + } + + public void setPoint(int xy){ + this.x = getX(xy); + this.y = getY(xy); + } + + public boolean equate(MapPoint mapPoint){ + if(this.x != mapPoint.x){ + return false; + } + if(this.y != mapPoint.y){ + return false; + } + return true; + } + + public boolean equate(int xy){ + if(this.x != getX(xy)){ + return false; + } + if(this.y != getY(xy)){ + return false; + } + return true; + } + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/util/MessageUtil.java b/serverlogic/src/main/java/com/ljsd/jieling/util/MessageUtil.java index 9bdcb22e5..7571410b6 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/util/MessageUtil.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/util/MessageUtil.java @@ -3,16 +3,16 @@ package com.ljsd.jieling.util; import com.google.protobuf.GeneratedMessage; import com.googlecode.protobuf.format.JsonFormat; import com.ljsd.jieling.db.mongo.MongoUtil; +import com.ljsd.jieling.logic.OnlineUserManager; import com.ljsd.jieling.netty.PackageConstant; import com.ljsd.jieling.netty.cocdex.Tea; import com.ljsd.jieling.network.session.ISession; -import com.ljsd.jieling.protocols.CommonProto; -import com.ljsd.jieling.protocols.MessageTypeProto; -import com.ljsd.jieling.protocols.PlayerInfoProto; +import com.ljsd.jieling.protocols.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; +import java.util.List; public class MessageUtil { @@ -50,6 +50,10 @@ public class MessageUtil { return Tea.encrypt2(bytes, secretKey); } + public static void sendMessage(int uid, int result, int msgId, GeneratedMessage generatedMessage, boolean flush) { + ISession sessionByUid = OnlineUserManager.getSessionByUid(uid); + sendMessage(sessionByUid, result, msgId, generatedMessage, flush); + } public static void sendMessage(ISession session, int result, int msgId, GeneratedMessage generatedMessage, boolean flush) { byte[] byteBuf = wrappedBuffer(session.getUid(), session.getToken(), session.getIndex(), result, msgId, generatedMessage); @@ -191,5 +195,56 @@ public class MessageUtil { // } // } + public static void sendRoomMatchResponse(ISession session, int responseMsgId, int type, boolean result) { + RoomProto.RoomMatchResponse.Builder builder = RoomProto.RoomMatchResponse.newBuilder(); + builder.setResult(result); + builder.setType(type); + sendMessage(session, 1, responseMsgId, builder.build(), true); + } + public static void sendRoomMatchSuccessIndication(int uid, int type, int roomId) { + RoomProto.RoomMatchSuccessIndication.Builder builder = RoomProto.RoomMatchSuccessIndication.newBuilder(); + builder.setRoomId(roomId); + builder.setType(type); + sendMessage(uid, 1, MessageTypeProto.MessageType.ROOM_MATCH_SUCCESS_INDICATION_VALUE, builder.build(), true); + } + + public static void sendRoomCancelMatchResponse(ISession session, int responseMsgId, int type, boolean result) { + RoomProto.RoomMatchResponse.Builder builder = RoomProto.RoomMatchResponse.newBuilder(); + builder.setResult(result); + builder.setType(type); + sendMessage(session, 1, responseMsgId, builder.build(), true); + } + + public static void sendRoomGameEndIndication(int uid, int roomId) { + RoomFightProto.RoomGameEndIndication.Builder builder = RoomFightProto.RoomGameEndIndication.newBuilder(); + builder.setRoomId(roomId); + sendMessage(uid, 1, MessageTypeProto.MessageType.ROOM_GAME_END_INDICATION_VALUE, builder.build(), true); + } + + public static void sendRoomStartGameReadyResponse(ISession session, int responseMsgId, int type) { + RoomProto.RoomStartGameReadyRequest.Builder builder = RoomProto.RoomStartGameReadyRequest.newBuilder(); + builder.setType(type); + sendMessage(session, 1, responseMsgId, builder.build(), true); + } + + public static void sendRoomStartGameIndication(int uid, int roomId, int type) { + RoomProto.RoomStartGameIndication.Builder builder = RoomProto.RoomStartGameIndication.newBuilder(); + builder.setRoomId(roomId); + builder.setType(type); + sendMessage(uid, 1, MessageTypeProto.MessageType.ROOM_START_GAME_INDICATION_VALUE, builder.build(), true); + } + + public static void sendRoomSyncMyselfMoveResponse(ISession session, int responseMsgId, long clientTimestamp) { + RoomFightProto.RoomSyncMyselfMoveResponse.Builder builder = RoomFightProto.RoomSyncMyselfMoveResponse.newBuilder(); + builder.setClientTimestamp(clientTimestamp); + builder.setServerTimestamp(System.currentTimeMillis()); + sendMessage(session, 1, responseMsgId, builder.build(), true); + } + public static void sendRoomSyncOtherMoveIndiction(int uid, List path) { + RoomFightProto.RoomSyncOtherMoveIndiction.Builder builder = RoomFightProto.RoomSyncOtherMoveIndiction.newBuilder(); + builder.setUid(uid); + builder.addAllTartXYs(path); + sendMessage(uid, 1, MessageTypeProto.MessageType.ROOM_SYNC_OTHER_MOVE_INDICTION_VALUE, builder.build(), true); + } } diff --git a/test/src/main/java/network/client/NettyClient.java b/test/src/main/java/network/client/NettyClient.java index d410f30bb..3510f56e4 100644 --- a/test/src/main/java/network/client/NettyClient.java +++ b/test/src/main/java/network/client/NettyClient.java @@ -20,9 +20,9 @@ public class NettyClient { private static final Logger LOGGER = LoggerFactory.getLogger(NettyClient.class); -// private static int uid = 10004436; + private static int uid = 10004555; private static int msgIndex = 1; - private static int uid = 10004481; +// private static int uid = 10004481; private static int token=543242; public static void main(String[] args) throws InterruptedException, InvalidProtocolBufferException { @@ -46,7 +46,7 @@ public class NettyClient { handler.sendRequest_jieling(makeFinalMessage(gameMessage, MessageTypeProto.MessageType.LOGIN_REQUEST_VALUE)); //获取好友信息 -// handler.sendRequest_jieling(makeFinalMessage(getFriends(), MessageTypeProto.MessageType.GET_FRIEND_INFO_REQUEST_VALUE)); + handler.sendRequest_jieling(makeFinalMessage(getFriends(), MessageTypeProto.MessageType.GET_FRIEND_INFO_REQUEST_VALUE)); //根据用户名查找玩家 // handler.sendRequest_jieling(makeFinalMessage(findUserByName(), MessageTypeProto.MessageType.FRIEND_SEARCH_REQUEST_VALUE)); //发送好友申请 @@ -56,9 +56,9 @@ public class NettyClient { //删除好友 // handler.sendRequest_jieling(makeFinalMessage(delFriend(), MessageTypeProto.MessageType.DEL_FRIEND_REQUEST_VALUE)); //赠送体力 - handler.sendRequest_jieling(makeFinalMessage(friendGive(), MessageTypeProto.MessageType.FRIEND_GIVE_PRESENT_REQUEST_VALUE)); +// handler.sendRequest_jieling(makeFinalMessage(friendGive(), MessageTypeProto.MessageType.FRIEND_GIVE_PRESENT_REQUEST_VALUE)); //领取体力 - handler.sendRequest_jieling(makeFinalMessage(takeHeart(), MessageTypeProto.MessageType.FRIEND_TAKE_HEART_REQUEST_VALUE)); +// handler.sendRequest_jieling(makeFinalMessage(takeHeart(), MessageTypeProto.MessageType.FRIEND_TAKE_HEART_REQUEST_VALUE)); //聊天 // for (int i= 0; i < 1000; i++){ // handler.sendRequest_jieling(makeFinalMessage(sendChatInfo(i), MessageTypeProto.MessageType.SEND_CHAT_INFO_REQUEST_VALUE)); @@ -138,14 +138,14 @@ public class NettyClient { private static MessageLite findUserByName() { PlayerInfoProto.FriendSearchRequest friendSearchRequest = PlayerInfoProto.FriendSearchRequest . newBuilder() - .setName("10004481") + .setName("王五") .build(); return friendSearchRequest; } private static MessageLite getFriends() { PlayerInfoProto.GetFriendInfoRequest getFriendInfoRequest = PlayerInfoProto.GetFriendInfoRequest - .newBuilder().setType(3) + .newBuilder().setType(2) .build(); return getFriendInfoRequest; }