init红中麻将

master
zhouwei 2026-02-06 18:21:12 +08:00
parent 263a7b9724
commit 0dcb0ab55d
21 changed files with 7204 additions and 0 deletions

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<gameSetting>
<host>8.134.76.43</host>
<intranet>8.134.76.43</intranet>
<port>8722</port>
<serverId>8722</serverId>
<gameId>22</gameId>
<loggerDebug>true</loggerDebug>
</gameSetting>

View File

@ -0,0 +1,20 @@
log4j.rootLogger = INFO,consoleAppender,fileAppender
# ConsoleAppender
log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n
# Regular FileAppender
log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log
log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n
log4j.appender.fileAppender.Encoding=UTF-8
log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.Append=true
# The file is rolled over very day
log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<serivce-core>
<log4jPath>log4j.properties</log4jPath>
<plugin>
<id>redis</id>
<class>com.taurus.core.plugin.redis.RedisPlugin</class>
<poolConfig>
<!-- 最大连接数, 默认8个 -->
<maxTotal>80</maxTotal>
<!-- 最大空闲连接数, 默认8个 -->
<maxIdle>20</maxIdle>
<!-- 最小空闲连接数, 默认0个 -->
<minIdle>5</minIdle>
<!-- 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1 -->
<maxWaitMillis>-1</maxWaitMillis>
<!-- 在borrow一个jedis实例时是否提前进行alidate操作, 默认false -->
<testOnBorrow>true</testOnBorrow>
<!-- 在return给pool时是否提前进行validate操作, 默认false -->
<testOnReturn>true</testOnReturn>
<!-- 表示有一个idle object evitor线程对idle object进行扫描如果validate失败
此object会被从pool中drop掉这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义, 默认true -->
<testWhileIdle>true</testWhileIdle>
<!-- 表示idle object evitor每次扫描的最多的对象数, 默认-1 -->
<numTestsPerEvictionRun>100</numTestsPerEvictionRun>
<!-- 表示一个对象至少停留在idle状态的最短时间然后才能被idle object evitor扫描并驱逐
这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义 , 默认60000-->
<minEvictableIdleTimeMillis>60000</minEvictableIdleTimeMillis>
<!-- 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认30000 -->
<timeBetweenEvictionRunsMillis>30000</timeBetweenEvictionRunsMillis>
<!-- 在minEvictableIdleTimeMillis基础上加入了至少minIdle个对象已经在pool里面了。
如果为-1evicted不会根据idle time驱逐任何对象。如果minEvictableIdleTimeMillisd大于0
则此项设置无意义且只有在timeBetweenEvictionRunsMillis大于0时才有意义默认1800000 -->
<softMinEvictableIdleTimeMillis>1800000</softMinEvictableIdleTimeMillis>
<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
<blockWhenExhausted>true</blockWhenExhausted>
</poolConfig>
<infos>
<info name="group1_db0" host="8.134.76.43" password="cssq@2020" port="6379" database="0" timeout="5000"/>
<info name="group1_db1" host="8.134.76.43" password="cssq@2020" port="6379" database="1" timeout="5000"/>
<info name="group1_db2" host="8.134.76.43" password="cssq@2020" port="6379" database="2" timeout="5000"/>
<info name="group1_db5" host="8.134.76.43" password="cssq@2020" port="6379" database="5" timeout="5000"/>
<info name="group1_db8" host="8.134.76.43" password="cssq@2020" port="6379" database="8" timeout="5000"/>
<info name="group1_db9" host="8.134.76.43" password="cssq@2020" port="6379" database="9" timeout="5000"/>
<info name="group1_db10" host="8.134.76.43" password="cssq@2020" port="6379" database="10" timeout="5000"/>
<info name="group1_db11" host="8.134.76.43" password="cssq@2020" port="6379" database="11" timeout="5000"/>
<info name="tmp_group1_db9" host="8.134.76.43" password="654sads" port="6479" database="9" timeout="5000"/>
</infos>
<!--<infos>
<info name="group1_db0" host="127.0.0.1" cssq@2020 port="6379" database="0" timeout="5000"/>
<info name="group1_db1" host="127.0.0.1" port="6379" database="1" timeout="5000"/>
<info name="group1_db2" host="127.0.0.1" port="6379" database="2" timeout="5000"/>
<info name="group1_db5" host="127.0.0.1" port="6379" database="5" timeout="5000"/>
<info name="group1_db8" host="127.0.0.1" port="6379" database="8" timeout="5000"/>
<info name="group1_db9" host="127.0.0.1" port="6379" database="9" timeout="5000"/>
<info name="group1_db10" host="127.0.0.1" port="6379" database="10" timeout="5000"/>
<info name="group1_db11" host="127.0.0.1" port="6379" database="11" timeout="5000"/>
</infos>-->
</plugin>
</serivce-core>

View File

@ -0,0 +1,75 @@
<server>
<!-- 计时器线程池大小-->
<timerThreadPoolSize>1</timerThreadPoolSize>
<!-- 协议包压缩门槛 (单位字节),当协议包大于设定的值则会进行压缩 -->
<protocolCompression>512</protocolCompression>
<!-- 读缓冲区类型 nio Direct Buffer 或者 Heap Buffer-->
<readBufferType>Heap</readBufferType>
<!-- 写入冲区类型 nio Direct Buffer 或者 Heap Buffer-->
<writeBufferType>Heap</writeBufferType>
<!-- 最大的数据包大小 -->
<maxPacketSize>524288</maxPacketSize>
<!-- 最大读取缓存大小 -->
<maxReadBufferSize>1024</maxReadBufferSize>
<!-- 最大写入缓存大小 -->
<maxWriteBufferSize>32768</maxWriteBufferSize>
<!-- 会话队列的大小-->
<sessionPacketQueueSize>160</sessionPacketQueueSize>
<!-- Thread Pool Size of the 3 main stages of the Bitswarm Engine -->
<socketAcceptorThreadPoolSize>1</socketAcceptorThreadPoolSize>
<socketReaderThreadPoolSize>2</socketReaderThreadPoolSize>
<socketWriterThreadPoolSize>1</socketWriterThreadPoolSize>
<!-- Enable disable Nagle algorithm on sockets, true == disable -->
<tcpNoDelay>true</tcpNoDelay>
<!-- 会话超时时间(单位秒)-->
<sessionTimeout>300</sessionTimeout>
<!-- Bind socket addresses -->
<socketAddresses>
<socket address="0.0.0.0" port="8722" type="TCP" />
</socketAddresses>
<!-- Ip addresses filter-->
<ipFilter>
<addressBlackList>
<string>1.2.3.4</string>
</addressBlackList>
<addressWhiteList>
<string>127.0.0.1</string>
</addressWhiteList>
<maxConnectionsPerAddress>10000</maxConnectionsPerAddress>
</ipFilter>
<webSocket>
<isActive>false</isActive>
<address>0.0.0.0</address>
<port>80</port>
</webSocket>
<!-- Main extension class -->
<extensionConfig>
<name>robot - test</name>
<className>robot.mj.EXMainServer</className>
</extensionConfig>
<!-- The system thread pool config -->
<systemThreadPoolConfig>
<name>Sys</name>
<corePoolSize>2</corePoolSize>
<maxPoolSize>8</maxPoolSize>
<keepAliveTime>60000</keepAliveTime>
<maxQueueSize>20000</maxQueueSize>
</systemThreadPoolConfig>
<!-- The extension thread pool config -->
<extensionThreadPoolConfig>
<name>Ext</name>
<corePoolSize>2</corePoolSize>
<maxPoolSize>8</maxPoolSize>
<keepAliveTime>60000</keepAliveTime>
<maxQueueSize>20000</maxQueueSize>
</extensionThreadPoolConfig>
</server>

View File

@ -0,0 +1,47 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.robot</groupId>
<artifactId>robot_mj_changsha</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>robot_mj_changsha</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.robot</groupId>
<artifactId>robot_common</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>robot</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<!-- <compilerArgument>-parameters</compilerArgument> -->
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,138 @@
package robot.mj;
public class Config {
public static final int FENGDING_SCORE = 28;
public static final int XIPAI_SCORE = 10;
public static final int ANCHOU_SCORE = 10;
public static final String ROOM_CONFIG_ZIMO = "zimo";
public static final String ROOM_CONFIG_ZHUANGXIAN = "zhuangxian";
public static final String ROOM_CONFIG_NIAO = "niao";
public static final String ROOM_CONFIG_NIAO_TYPE = "niao_type";
public static final String ROOM_CONFIG_PIAO_NIAO = "piao_niao"; //0:不嫖 1:自由票 2:固定票
public static final String ROOM_CONFIG_PIAO_NIAO_AUTO = "auto_piao"; //piao fen
public static final String ROOM_CONFIG_PIAO_NIAO_OPT = "piao_niao_opt"; //piao fen
public static final String ROOM_CONFIG_ZT_LIULIUSHUN = "zhongtuliuliushun";
public static final String ROOM_CONFIG_ZT_DASIXI = "zhongtusixi";
public static final String ROOM_CONFIG_QS_JIEJIEGAO = "jiejiegao";
public static final String ROOM_CONFIG_QS_SANTONG = "santong";
public static final String ROOM_CONFIG_QS_YIZHIHUA = "yizhihua";
public static final String ROOM_CONFIG_QUEYIMEN = "queyimen";
public static final String ROOM_CONFIG_FENGDING = "fengding";
public static final String ROOM_CONFIG_FENGDING_SCORE = "fengding_score";
public static final String ROOM_CONFIG_XIPAI = "xi_pai";
public static final String ROOM_CONFIG_XIPAI_SCORE = "xi_pai_score";
public static final String ROOM_CONFIG_ANCHOU_SCORE = "an_chou_score";
public static final String ROOM_CONFIG_DIFEN_SCORE = "difen_score";
public static final String ROOM_CONFIG_NIAOFEN_SCORE = "niaofen_score";
public static final String ROOM_CONFIG_NIAOFEN_OPT = "niaofen_opt"; //0中鸟加分//1中鸟加倍
public static final String ROOM_CONFIG_KAI_GONG = "kai_gong"; //0:开杠2张1:开杠四张
public static final int NIAO_TYPE_ADD = 0;
public static final int NIAO_TYPE_DOUBLE = 1;
public static final int NIAO_TYPE_CS2NIAO = 2;
public static final String ROOM_CONFIG_QS_JTYN = "two_pair";
public static final String ROOM_CONFIG_NO_JIANG = "no_jiang";
public static final String ROOM_CONFIG_NATIVE_HU = "native_hu";
public static final String ROOM_CONFIG_FOUR_WIN = "four_win";
public static final String SETTLE_XIAO_DIAN_PAO = "xiao_dian_pao";
public static final String SETTLE_XIAO_JIE_PAO = "xiao_jie_pao";
public static final String SETTLE_XIAO_ZIMO = "xiao_zimo";
public static final String SETTLE_DA_DIAN_PAO = "da_dian_pao";
public static final String SETTLE_DA_JIE_PAO = "da_jie_pao";
public static final String SETTLE_DA_ZIMO = "da_zimo";
public static final String GAME_EVT_PLAYER_DEAL = "811";
public static final String GAME_DIS_CARD = "611";
public static final String GAME_EVT_DISCARD = "812";
public static final String GAME_EVT_DISCARD_TIP = "813";
public static final String GAME_EVT_FZTIPS = "814";
public static final String GAME_ACTION = "612";
public static final String GAME_EVT_ACTION = "815";
public static final String GAME_EVT_HU = "816";
public static final String GAME_EVT_RESULT1 = "817";
public static final String GAME_EVT_RESULT2 = "818";
public static final String GAME_EVT_DRAW = "819";
public static final String GAME_EVT_CHANGE_ACTIVE_PLAYER = "820";
public static final String GAME_EVT_NIAO = "821";
public static final String GAME_EVT_QSTIP = "822";
public static final String GAME_EVT_QSWIN = "823";
public static final String GAME_EVT_OPENKONG = "824";
public static final String GAME_EVT_HAIDITIP = "825";
public static final String GAME_EVT_PIAONIAO_TIP = "833";
public static final String GAME_EVT_PIAONIAO = "834";
public static final String GAME_EVT_TING_TIP = "835";
public static final String GAME_EVT_TING = "836";
public static final String CREATE_ROOM_ROBOT = "create_room_for_robot";
public static final String INIT_CONNECTION = "init_connection";
/**
* - robot_mgr to robot_mj_cs
*/
public static final String JOIN_ROOM = "2002";
/**
* - robot_mgr to robot_mj_cs
*/
public static final String GAME_READY = "2003";
/**
* 退 - robot_mgr to robot_mj_cs
*/
public static final String EXIT_ROOM = "2005";
/**
* - robot_mgr to robot_mj_cs
*/
public static final String RECONNECT = "2006";
/**
* - robot_mj_cs to game_mj_cs
*/
public static final String GAME_READY_CS = "1003";
/**
* - robot_mgr to game_mj_cs
*/
public static final String JOIN_ROOM_CS = "1002";
/**
* 退 - robot_mgr to game_mj_cs
*/
public static final String EXIT_ROOM_CS = "1005";
}

View File

@ -0,0 +1,9 @@
package robot.mj;
public class EXActionEvent {
public static final String EVENT_ACTION = "action";
public static final String EVENT_DISCARD = "discard";
}

View File

@ -0,0 +1,413 @@
package robot.mj;
import com.robot.GameController;
import com.robot.GameInterceptor;
import com.robot.MainServer;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.routes.ActionKey;
import com.taurus.permanent.data.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import robot.mj.info.RobotUser;
import taurus.client.TaurusClient;
import taurus.client.business.GroupRoomBusiness;
import taurus.util.ROBOTEventType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* -
*/
public class EXGameController extends GameController {
private static final Logger log = LoggerFactory.getLogger(EXGameController.class);
private static final RobotConnectionManager robotConnectionManager = new RobotConnectionManager();
//机器人房间
protected static final Map<String, RobotUser> robotRoomMapping = new ConcurrentHashMap<>();
public EXGameController() {
super();
log.info("红中麻将游戏控制器已初始化");
}
/**
* /
*/
@ActionKey(value = Config.INIT_CONNECTION, validate = GameInterceptor.NOT_PLAYER)
public void handleInitialization(Session session, ITObject params, int gid) {
try {
log.info("收到客户端初始化请求Session: {}, GID: {}, 参数: {}", session, gid, params);
String type = params.getString("type");
String client = params.getString("client");
log.info("客户端类型: {}, 客户端标识: {}", type, client);
//验证参数
if ("robot_mj_cs".equals(type) && "robot_mgr".equals(client)) {
//返回成功响应
ITObject response = TObject.newInstance();
response.putString("status", "success");
response.putString("message", "初始化成功");
log.info("客户端初始化成功,发送响应");
MainServer.instance.sendResponse(gid, 0, response, session);
} else {
log.warn("客户端初始化失败,参数验证不通过: type={}, client={}", type, client);
ITObject response = TObject.newInstance();
response.putString("status", "failed");
response.putString("message", "参数验证失败");
MainServer.instance.sendResponse(gid, 1, response, session);
}
} catch (Exception e) {
log.error("处理初始化请求时发生错误", e);
ITObject response = TObject.newInstance();
response.putString("status", "error");
response.putString("message", "服务器内部错误: " + e.getMessage());
MainServer.instance.sendResponse(gid, 1, response, session);
}
}
/**
* robot_mgr
*/
@ActionKey(value = Config.CREATE_ROOM_ROBOT, validate = GameInterceptor.NOT_PLAYER)
public void createRoomForRobot(Session session, ITObject params, int gid) {
try {
int reqGroupId = params.getInt("groupId");
int wanfaId = params.getInt("wanfaId");
int robotId = params.getInt("robotId");
//使用统一的房间创建器在Redis中创建房间
RoomCreator.RoomInfo roomInfo = RoomCreator.createRoomInRedis(reqGroupId, wanfaId, robotId);
if (roomInfo != null) {
//返回房间信息给robot_mgr
ITObject response = TObject.newInstance();
response.putString("roomKey", roomInfo.getRoomId());
response.putInt("groupId", roomInfo.getGroupId());
response.putInt("wanfaId", roomInfo.getWanfaId());
response.putInt("robotId", robotId);
response.putString("server_ip", roomInfo.getServerIp());
response.putInt("server_port", roomInfo.getServerPort());
log.info("成功创建房间房间ID: {}", roomInfo.getRoomId());
//使用Taurus框架方法发送响应
MainServer.instance.sendResponse(gid, 0, response, session);
} else {
log.error("创建房间失败群组ID: {}, 玩法ID: {}", reqGroupId, wanfaId);
}
} catch (Exception e) {
log.error("处理创建房间请求时发生错误", e);
}
}
/**
* robot_mgr
*/
@ActionKey(value = Config.JOIN_ROOM, validate = GameInterceptor.NOT_PLAYER)
public void joinRoom(Session session, ITObject params, int gid) {
try {
String connecId = params.getString("connecId");
TaurusClient client = getCsMjGameServerConnection(connecId);
System.out.println("接收来自robot_mgr的加入房间协议 connecId: = "+connecId);
System.out.println("接收来自robot_mgr的加入房间协议 client: = "+client);
if (client == null) {
ITObject errorResponse = TObject.newInstance();
errorResponse.putString("status", "failed");
errorResponse.putString("message", "无法获取游戏服务器连接");
MainServer.instance.sendResponse(gid, 1, errorResponse, session);
return;
}
//设置session和token
String sessionToken = params.getString("session");
String robotSession = null;
String token = null;
if (sessionToken != null && sessionToken.contains(",")) {
String[] sessionParts = sessionToken.split(",");
if (sessionParts.length >= 2) {
robotSession = sessionParts[0];
token = sessionParts[1];
robotConnectionManager.setSessionAndToken(robotSession, token, connecId);
}
}
Integer groupId = params.getInt("groupId");
String roomId = params.getString("roomId");
String robotId = params.getString("robotId");
GroupRoomBusiness.joinRoom(groupId, roomId, robotSession, null);
Thread.sleep(5000);
params.del("groupId");
params.del("roomId");
params.del("connecId");
//发送加入房间请求到game_mj_cs
client.send(Config.JOIN_ROOM_CS, params, response -> {
System.out.println("joinRoomController: " + response);
RobotUser roomInfo = new RobotUser();
roomInfo.setCurrentRoomId(Integer.parseInt(roomId));
roomInfo.setConnecId(connecId);
roomInfo.setUserId(0);
//机器人房间映射关系
robotRoomMapping.put(robotId, roomInfo);
});
ITObject paramsReq = TObject.newInstance();
paramsReq.putString("status", "success");
MainServer.instance.sendResponse(gid, 0, paramsReq, session);
} catch (Exception e) {
log.error("处理加入房间请求时发生错误", e);
ITObject errorResponse = TObject.newInstance();
errorResponse.putString("status", "error");
errorResponse.putString("message", "处理加入房间请求时发生错误: " + e.getMessage());
MainServer.instance.sendResponse(gid, 1, errorResponse, session);
}
}
/**
* robot_mgr
*/
@ActionKey(value = Config.GAME_READY, validate = GameInterceptor.NOT_PLAYER)
public void robotReadyRoom(Session session, ITObject params, int gid) {
try {
String connecId = params.getString("connecId");
TaurusClient client = getCsMjGameServerConnection(connecId);
System.out.println("接收来自robot_mgr的机器人准备协议 connecId: = "+connecId);
System.out.println("接收来自robot_mgr的机器人准备协议 client: = "+client);
if (client == null) {
ITObject errorResponse = TObject.newInstance();
errorResponse.putString("status", "failed");
errorResponse.putString("message", "无法获取游戏服务器连接");
MainServer.instance.sendResponse(gid, 1, errorResponse, session);
return;
}
params.del("connecId");
Thread.sleep(1000);
//发送准备请求到game_mj_cs
client.send(Config.GAME_READY_CS, params, response -> {
System.out.println("robotReadyRoom: " + response);
});
ITObject paramsReq = TObject.newInstance();
paramsReq.putString("status", "success");
MainServer.instance.sendResponse(gid, 0, paramsReq, session);
} catch (Exception e) {
log.error("处理机器人准备请求时发生错误", e);
ITObject errorResponse = TObject.newInstance();
errorResponse.putString("status", "error");
errorResponse.putString("message", "服务器内部错误: " + e.getMessage());
MainServer.instance.sendResponse(gid, 1, errorResponse, session);
}
}
/**
* web_group
*/
@ActionKey(value = "225", validate = GameInterceptor.NOT_PLAYER)
public void webGroup(Session session, ITObject params, int gid) {
int robotId = params.getInt("robotid");
String roomId = params.getString("roomid");
int groupId = params.getInt("groupid");
//防止玩家操作同一房间 导致其他机器人加入
List<RobotUser> robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId));
if (!robotUsers.isEmpty()) {
synchronized (robotUsers) {
RobotUser robotUser = robotUsers.get(0);
if (robotId != Integer.parseInt(robotUser.getRobotId())) {
System.err.println("房间{"+ roomId +"}中已有机器人{"+robotUser.getRobotId()+"},当前机器人{"+robotId+"}不执行加入逻辑");
return;
}
}
}
System.err.println("225开始进房间: "+"room:"+ roomId +"robot:"+robotId);
//加入房间
joinRoomCommon(robotId, roomId, groupId, params);
System.err.println("225已进入房间准备成功: "+"room:"+ roomId +"robot:"+robotId);
}
/**
* web_group
*/
@ActionKey(value = "226", validate = GameInterceptor.NOT_PLAYER)
public void webGroupActive(Session session, ITObject params, int gid) {
int robotId = params.getInt("robotid");
String roomId = params.getString("roomid");
System.err.println("226开始进房间: " + "room:" + roomId + "robot:" + robotId);
//加入房间
joinRoomCommon(params.getInt("robotid"), params.getString("roomid"), params.getInt("groupid"), params);
System.err.println("226已进入房间准备成功: " + "room:" + roomId + "robot:" + robotId);
}
/**
* 线
* */
public void webGroupJoinRoom(RobotUser robotUser) {
String connecId = robotUser.getConnecId();
Jedis jedis0 = Redis.use("group1_db0").getJedis();
Jedis jedis2 = Redis.use("group1_db2").getJedis();
//重启检查
try {
Set<String> robotTokens = jedis0.smembers("{user}:"+robotUser.getRobotId()+"_token");
String robotSession = null;
for (String token : robotTokens) {
if (jedis0.exists(token)) {
robotSession = token;
break;
}
}
String gallrobot = jedis2.hget("gallrobot", robotUser.getRobotId());
if (gallrobot.equals("0")) {
robotRoomMapping.remove(connecId);
return;
}
System.err.println("重启后开始进房间: " + "room:" + robotUser.getCurrentRoomId() + "robot:" + robotUser.getRobotId());
ITObject params = new TObject();
params.putString("session", "{user}:" + robotUser.getRobotId() + "," + robotSession);
//加入房间
joinRoomCommon(Integer.parseInt(robotUser.getRobotId()), String.valueOf(robotUser.getCurrentRoomId()), Integer.parseInt(robotUser.getRobotGroupid()), params);
System.err.println("重启后已进入房间准备成功: " + "room:" + robotUser.getCurrentRoomId() + "robot:" + robotUser.getRobotId());
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
jedis0.close();
jedis2.close();
}
}
/**
*
*/
private void joinRoomCommon(int robotId, String roomId, int groupId, ITObject params) {
Jedis jedis0 = Redis.use("group1_db0").getJedis();
Jedis jedis2 = Redis.use("group1_db2").getJedis();
try {
Set<String> robotTokens = jedis0.smembers("{user}:" + robotId + "_token");
String robotSession = null;
for (String token : robotTokens) {
if (jedis0.exists(token)) {
robotSession = token;
break;
}
}
System.err.println("开始进房间: room:" + roomId);
System.err.println("开始进房间: {user}:" + robotId);
TaurusClient client = getCsMjGameServerConnection(roomId + "_" + robotId);
GroupRoomBusiness.joinRoom(groupId, "room:" + roomId, "{user}:" + robotId, null);
//机器人房间映射关系
RobotUser robotUser = getRobotRoomInfo(String.valueOf(robotId));
String connecId = roomId + "_" + robotId;
if (robotUser.getCurrentRoomId() == 0) {
robotUser.setCurrentRoomId(Integer.parseInt(roomId));
robotUser.setClient(client);
robotUser.setConnecId(connecId);
}
robotRoomMapping.put(robotUser.getConnecId(), robotUser);
robotRoomMapping.remove(robotUser.getRobotId());
Thread.sleep(2000);
params.putString("session", "{user}:" + robotId + "," + robotSession);
//发送加入房间请求到game_mj_cs
client.send(Config.JOIN_ROOM_CS, params, response -> {
robotConnectionManager.reconnectToGameServer(response, robotUser, client);
});
System.err.println("已进入房间成功: " + robotUser.getConnecId());
Thread.sleep(1000);
if (client.isConnected()) {
client.send(Config.GAME_READY_CS, params, response -> {
System.out.println("1003:" + response);
});
jedis2.hset("gallrobot", String.valueOf(robotUser.getRobotId()), "1");
robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_READY);
robotConnectionManager.setSessionAndToken("{user}:" + robotId, robotSession, robotUser.getConnecId());
}
robotUser.setIntoRoomTime(robotConnectionManager.getTime());
System.err.println("已进入房间准备成功: " + robotUser.getConnecId());
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
jedis0.close();
jedis2.close();
}
}
/**
* ID
*/
public static RobotUser getRobotRoomInfo(String robotId) {
RobotUser robotUser = robotRoomMapping.get(robotId);
if (robotUser ==null) {
RobotUser robotUserCopy = new RobotUser();
robotUserCopy.setRobotId(robotId);
robotUserCopy.setPassword("123456");
robotUserCopy.setGameHost("8.134.76.43");
robotUserCopy.setGamePort("6421");
robotUserCopy.setRobotGroupid("330800");
robotUserCopy.setRobotPid("22");
return robotUserCopy;
}
return robotRoomMapping.get(robotId);
}
/**
* IDRobotUser
*/
public List<RobotUser> getRobotUsersByRoomId(int roomId) {
String prefix = roomId + "_";
List<RobotUser> result = new ArrayList<>();
for (Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
if (entry.getKey().startsWith(prefix)) {
result.add(entry.getValue());
}
}
return result;
}
/**
* ID
*/
public static void removeRobotRoomInfo(String robotId) {
robotRoomMapping.remove(robotId);
}
/**
* IDID
* robotIdconnectionId
*/
public static TaurusClient getCsMjGameServerConnection(String connecId) {
TaurusClient taurusClient = robotConnectionManager.getGameClient(connecId);
System.out.println("根据机器人ID和连接ID获取红中麻将游戏服务器连接 client: = "+taurusClient);
if (taurusClient != null) {
log.debug("成功获取游戏服务器连接connecId: {}", connecId);
return taurusClient;
}
taurusClient = robotConnectionManager.connectToGameServer(connecId);
return taurusClient;
}
}

View File

@ -0,0 +1,164 @@
package robot.mj;
import java.util.Map;
import com.robot.GameController;
import com.robot.MainServer;
import com.robot.data.Player;
import com.robot.data.Room;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.permanent.TPServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import robot.mj.info.RobotUser;
import taurus.client.NetManager;
import taurus.client.TaurusClient;
import java.util.concurrent.TimeUnit;
import static robot.mj.EXGameController.robotRoomMapping;
/**
*
* TCProbot_mgr game_mj_csAI
*/
public class EXMainServer extends MainServer{
private static final Logger log = LoggerFactory.getLogger(EXMainServer.class);
private static final RobotConnectionManager robotConnectionManager = new RobotConnectionManager();
private static final EXGameController exGameController = new EXGameController();
private volatile boolean connectionCheckRunning = true;
@Override
public void onStart() {
super.onStart();
// 1. 先启动独立的事件处理线程(只启动一次)
startNetEventThread();
// 2. 启动连接检查定时任务
//startConnectionCheckScheduler();
//测试
Jedis jedis2 = Redis.use("group1_db2").getJedis();
String robotskey = "g{"+762479+"}:play:"+22;
Map<String, String> maprobot = jedis2.hgetAll(robotskey);
for(Map.Entry<String, String> entry : maprobot.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
//是否创建
RobotUser robotUser = new RobotUser();
robotUser.setRobotId(entry.getKey());
robotUser.setPassword("123456");
robotUser.setGameHost("8.134.76.43");
robotUser.setGamePort("6421");
robotUser.setRobotGroupid("762479");
robotUser.setRobotPid("22");
robotRoomMapping.put(entry.getKey(), robotUser);
}
for(Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
RobotUser robotUser = entry.getValue();
//1、登录
//判断是否登录
if(!robotUser.isLogin){
robotConnectionManager.login(robotUser);
}
}
// TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() {
// @Override
// public void run() {
//
// for(Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
// RobotUser robotUser = entry.getValue();
// //1、登录
// //判断是否登录
// if(!robotUser.isLogin){
// robotConnectionManager.login(robotUser);
// }
// /*//2、链接
// //判断是否链接
// System.out.println("robotUser.isconnect"+robotUser.getIsconnect());
// if(!robotUser.getIsconnect()){
// robotConnectionManager.connectGame(robotUser);
// }else{
// robotConnectionManager.renconnect(robotUser);
// }
//
//
// //4、加入房间
// if(robotUser.getStatus()==0){
// //没状态时候进入加入房间
// ITObject params = new TObject();
// params.putString("connecId", robotUser.getRoomId()+"_"+robotUser.getRobotId());
// params.putString("roomId", robotUser.getRoomId());
// params.putString("groupId", robotUser.getRobotGroupid());
// params.putString("session", "{user}:"+robotUser.getRobotId());
// exGameController.joinRoom(null, params, robotUser.getClient().getId());
// }
// System.out.println("robotUser.getIntoRoomTime()"+robotUser.getIntoRoomTime());
// System.out.println("robGetTiem"+robotConnectionManager.getTime());
// if(robotUser.getIntoRoomTime()+6<=robotConnectionManager.getTime()){
// //5、退出房间
// robotConnectionManager.outoRoom(robotUser);
// }*/
//
// }
// }
// }, 0, 5 ,TimeUnit.SECONDS);
//5、干活
log.info("红中麻将机器人服务器已启动");
log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port);
jedis2.close();
}
/**
* 线
*/
private void startNetEventThread() {
Thread eventThread = new Thread(() -> {
while (true) {
NetManager.processEvents();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
break;
} catch (Exception e) {
}
}
}, "NetEvent-Thread");
eventThread.setDaemon(true); // 设置为守护线程
eventThread.start();
}
@Override
public Room newRoom(String roomid, Map<String, String> redis_room_map) {
return new EXRoom(roomid, redis_room_map);
}
@Override
public Player newPlayer(int i, Room room, String s) {
return new EXPlayer(i, room, s);
}
protected GameController newController() {
return new EXGameController();
}
@Override
public void onStop() {
super.onStop();
// 停止连接检查线程
connectionCheckRunning = false;
log.info("红中麻将机器人服务器已停止");
}
}

View File

@ -0,0 +1,31 @@
package robot.mj;
import com.robot.Util;
import com.robot.data.Player;
import com.robot.data.Room;
import com.robot.data.Score;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import java.util.*;
/**
*
*
*/
public class EXPlayer extends Player {
public EXPlayer(int playerid, Room table, String session_id) {
super(playerid, table, session_id);
System.out.println("new robot ");
}
public EXRoom getRoom() {
return (EXRoom) room;
}
}

View File

@ -0,0 +1,53 @@
package robot.mj;
import com.robot.data.Room;
import java.util.Map;
public class EXRoom extends Room {
//
public EXRoom(String roomid, Map<String, String> redis_room_map) {
super(roomid, redis_room_map);
}
public void checkAction() {
}
@Override
protected void roomResult() {
}
@Override
public void endGame() {
super.endGame();
}
@Override
public void saveMilitaryTotal(boolean dissmiss) {
super.saveMilitaryTotal(dissmiss);
}
@Override
public void clear() {
super.clear();
}
}

View File

@ -0,0 +1,600 @@
package robot.mj;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.events.Event;
import com.taurus.core.events.IEventListener;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.ICallback;
import com.taurus.core.util.StringUtil;
import robot.mj.business.AccountBusiness;
import robot.mj.handler.HuNanHongZhong;
import robot.mj.info.RobotUser;
import taurus.client.Message;
import taurus.client.MessageResponse;
import taurus.client.TaurusClient;
import taurus.client.SocketCode;
import redis.clients.jedis.Jedis;
import java.util.*;
import java.util.concurrent.*;
import static robot.mj.EXGameController.robotRoomMapping;
/**
* -
*/
public class RobotConnectionManager {
private static final Map<String, HuNanHongZhong> huNanHongZhongInstances = new ConcurrentHashMap<>();
private final EXGameController exGameController;
private final String host="8.134.76.43";
private final int port=6421;
public RobotConnectionManager() {
exGameController = new EXGameController();
}
/**
*
*/
private HuNanHongZhong getHuNanHongZhongInstance(String connecId) {
HuNanHongZhong existingInstance = huNanHongZhongInstances.get(connecId);
if (existingInstance != null) {
return existingInstance;
}
HuNanHongZhong newInstance = new HuNanHongZhong();
//从Redis恢复状态
boolean restored = newInstance.restoreFromRedis(connecId);
if (restored) {
System.out.println("从Redis恢复HuNanHongZhong实例: " + connecId);
} else {
System.out.println("创建新的HuNanHongZhong实例: " + connecId);
}
huNanHongZhongInstances.put(connecId, newInstance);
System.out.println("当前HuNanHongZhong实例总数: " + huNanHongZhongInstances.size());
return newInstance;
}
/**
*
*/
public void setSessionAndToken(String session, String token, String connecId) {
HuNanHongZhong instance = getHuNanHongZhongInstance(connecId);
instance.session = session;
instance.token = token;
}
/**
*
*/
public TaurusClient connectToGameServer(String connecId) {
try {
//创建Taurus客户端
TaurusClient client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);
//设置事件监听器
setupEventListeners(client, connecId);
client.connect();
return client;
} catch (Exception e) {
return null;
}
}
/**
*
*/
public void disconnectFromGameServer(String connecId) {
System.out.println("开始主动断开连接: {"+connecId+"}");
RobotUser robotUser = robotRoomMapping.remove(connecId);
//清理连接数据
if (connecId != null) {
HuNanHongZhong.removeFromRedis(connecId);
HuNanHongZhong instance = huNanHongZhongInstances.get(connecId);
if (instance != null) {
instance.getHongZhongCardInhand().clear();
instance.getChuGuoCardInhand().clear();
System.out.println("清空HuNanHongZhong集合数据: " + connecId);
}
huNanHongZhongInstances.remove(connecId);
}
if (robotUser != null) {
TaurusClient client = robotUser.getClient();
if (client != null) {
try {
if (client.isConnected()) {
client.killConnection();
}
System.out.println("客户端主动断开连接完成: {"+connecId+"}");
} catch (Exception e) {
System.out.println("断开客户端连接时发生异常: " + connecId + ", 错误: " + e.getMessage());
}
} else {
System.out.println("客户端连接不存在: {"+connecId+"}");
}
}
}
/**
*
*/
public void setupEventListeners(TaurusClient client, String connecId) {
//添加消息事件监听器
IEventListener messageListener = new IEventListener() {
@Override
public void handleEvent(Event event) {
//获取 msg
Message message = (Message) event.getParameter("msg");
ITObject param = message.param;
//回调协议号
String command = message.command;
System.out.println("csmj OnEvent msg " + command);
//根据玩法ID处理不同的回调
if (StringUtil.isNotEmpty(command)) {
//直接处理协议
handleProtocol(command, message, client, connecId);
}
}
};
//添加连接状态监听器
IEventListener connectListener = new IEventListener() {
@Override
public void handleEvent(Event event) {
Message message = (Message) event.getParameter("msg");
SocketCode code = (SocketCode) event.getParameter("code");
}
};
//注册事件监听器
client.addEventListener(TaurusClient.NetClientEvent.OnEvent, messageListener);
client.addEventListener(TaurusClient.NetClientEvent.Connect, connectListener);
}
/**
* 线
*/
public void reconnectToGameServer(MessageResponse response, RobotUser robotUser, TaurusClient client) {
String connecId = robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId();
if(client.isConnected()){
ITObject obj = response.messageData.param.getTObject("tableInfo");
ITObject reloadInfo = response.messageData.param.getTObject("reloadInfo");
if (obj!=null) {
//处理 seat
//获取机器人的seat
ITArray playerData = obj.getTArray("playerData");
for (int i = 0; i < playerData.size(); i++) {
ITObject tms = playerData.getTObject(i);
Integer tmuserid = tms.getInt("aid");
if(tmuserid==Integer.parseInt(robotUser.getRobotId())){
Integer seat = tms.getInt("seat");
robotUser.setSeat(seat);
}
}
System.out.println("playerData:"+playerData);
System.out.println("obj:"+obj);
System.out.println("reloadInfo:"+reloadInfo);
if(reloadInfo!=null) {
//重连回来的
int curren_outcard_seat = reloadInfo.getInt("curren_outcard_seat");
if(curren_outcard_seat== robotUser.getSeat()){
//同步手牌
ITArray hand_card = reloadInfo.getTArray("hand_card");
ITArray info_list = reloadInfo.getTArray("info_list");
List<Integer> hcard = new ArrayList<>();
if(hand_card!=null) {
for (int i = 0; i < hand_card.size(); i++) {
hcard.add(hand_card.getInt(i));
}
}
ITArray outcard_list = new TArray();
if(info_list!=null) {
for (int i = 0; i < info_list.size(); i++) {
ITObject tms = info_list.getTObject(i);
Integer playerid = tms.getInt("playerid");
if(playerid==Integer.parseInt(robotUser.getRobotId())){
outcard_list = tms.getTArray("outcard_list");
}
}
}
System.out.println("hcard>0"+hcard);
if(hcard.size()>0){
//同步手牌
HuNanHongZhong currentInstance = getHuNanHongZhongInstance(connecId);
//同步逻辑比较手牌数量
List<Integer> currentHand = currentInstance.getHongZhongCardInhand();
if (currentHand.isEmpty() || hcard.size() > currentHand.size()) {
//手牌集合为空 或者 玩家出牌了
currentInstance.updateHandCard(hcard);
System.out.println("断线重连:同步手牌数据,服务器手牌:" + hcard);
} else {
System.out.println("断线重连使用Redis恢复的手牌数据数量:" + currentHand.size());
}
if(outcard_list.size()>0){
List<Integer> outcards = new ArrayList<>();
for (int i = 0; i < outcard_list.size(); i++) {
outcards.add(outcard_list.getInt(i));
}
//检查出牌记录是否需要同步
List<Integer> currentOutCards = currentInstance.getChuGuoCardInhand();
if (currentOutCards.isEmpty() || outcards.size() > currentOutCards.size()) {
currentInstance.updateOutCard(outcards);
System.out.println("断线重连:同步出牌数据,服务器出牌:" + outcards);
} else {
System.out.println("断线重连使用Redis恢复的出牌数据数量:" + currentOutCards.size());
}
}
sleepTime(2000);
currentInstance.outCard(client);
} else {
System.err.println("警告:重连时未获取到手牌数据");
}
}
}
}
}else {
renconnect(robotUser);
}
}
/**
*
*/
private void handleProtocol(String command, Message message, TaurusClient client, String connecId) {
RobotUser robotUser = robotRoomMapping.get(connecId);
int robotId = Integer.parseInt(robotUser.getRobotId());
ITObject param = message.param;
HuNanHongZhong huNanHongZhong = getHuNanHongZhongInstance(connecId);
Jedis jedis0 = Redis.use().getJedis();
Jedis jedis2 = Redis.use("group1_db2").getJedis();
try {
//红中麻将 机器人处理事件
//出牌广播
if ("812".equalsIgnoreCase(command)) {
huNanHongZhong.drawCard(command, message);
//处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
currentInstance.saveToRedis(connecId);
}
//初始化手牌
else if ("811".equalsIgnoreCase(command)) {
huNanHongZhong.cardInHead(command, message, client);
//处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
currentInstance.saveToRedis(connecId);
}
//摸牌
else if ("819".equalsIgnoreCase(command)) {
huNanHongZhong.getCard(command, message);
//处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
currentInstance.saveToRedis(connecId);
}
//出牌,牌权
else if ("813".equalsIgnoreCase(command)) {
huNanHongZhong.outCard(client);
//处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
currentInstance.saveToRedis(connecId);
}
//结算
else if ("817".equalsIgnoreCase(command)) {
huNanHongZhong.getHongZhongCardInhand().clear();
huNanHongZhong.getChuGuoCardInhand().clear();
System.out.println("红中结算");
Integer type = param.getInt("type");
if (type == 1 || type == 2) { //为1 为大结算 为2为解散,都需要恢复数据
//更新机器人剩余数量
updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
}
ITObject params = TObject.newInstance();
params.putString("session", client.getSession());
client.send("1003", params, new ICallback<MessageResponse>() {
@Override
public void action(MessageResponse messageResponse) {
}
});
}
//杠碰胡通知协议
else if ("814".equalsIgnoreCase(command)) {
huNanHongZhong.actionCard(param, client);
//处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
currentInstance.saveToRedis(connecId);
} else if ("820".equalsIgnoreCase(command)) {
HuNanHongZhong.changePlayer(command, message);
//处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
currentInstance.saveToRedis(connecId);
}
//服务器通知客户端有玩家执行了操作
else if ("815".equalsIgnoreCase(command)) {
huNanHongZhong.shanchuchuguopai(param);
//处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
currentInstance.saveToRedis(connecId);
}
//玩家加入房间
else if ("2001".equalsIgnoreCase(command)) {
CompletableFuture.runAsync(() -> {
sleepTime(6000);
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
//查询该房间的玩家信息
String playersStr = jedis0.hget("room:"+roomKey, "players");
if (!playersStr.equals("[]")) {
String players = playersStr.substring(1, playersStr.length() - 1);
String[] playerIds = players.split(",");
//判断只有当前机器人一个玩家
if (playerIds.length == 1) {
int playerId = Integer.parseInt(playerIds[0].trim());
if (playerId == robotId) {
//发送退出房间协议
ITObject params = TObject.newInstance();
client.send("1005", params, response -> {
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
//更新机器人剩余数量
updateLeftoverRobot(robotId);
disconnectFromGameServer(connecId);
System.out.println("2002发送退出房间协议1005robotId: {"+robotId+"}");
});
}
}
}
});
System.out.println("玩家{"+ robotUser.getCurrentRoomId()+"}加入房间:"+ param);
}
//玩家退出房间也要检查
else if ("2002".equalsIgnoreCase(command)) {
CompletableFuture.runAsync(() -> {
sleepTime(6000);
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
//查询该房间的玩家信息
String playersStr = jedis0.hget("room:"+roomKey, "players");
if (!playersStr.equals("[]")) {
String players = playersStr.substring(1, playersStr.length() - 1);
String[] playerIds = players.split(",");
//判断只有当前机器人一个玩家
if (playerIds.length == 1) {
int playerId = Integer.parseInt(playerIds[0].trim());
if (playerId == robotId) {
//发送退出房间协议
ITObject params = TObject.newInstance();
client.send("1005", params, response -> {
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
//更新机器人剩余数量
updateLeftoverRobot(robotId);
disconnectFromGameServer(connecId);
System.out.println("2002发送退出房间协议1005robotId: {"+robotId+"}");
});
}
}
}
});
}
//玩家解散房间
else if ("2005".equalsIgnoreCase(command)) {
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
//更新机器人剩余数量
updateLeftoverRobot(robotId);
disconnectFromGameServer(connecId);
System.out.println("2005玩家发送解散房间协议robotId: {"+robotId+"}");
}
//解散房间时候恢复机器人账号可以使用
else if ("2008".equalsIgnoreCase(command)) {
updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
disconnectFromGameServer(connecId);
}
else if ("2009".equalsIgnoreCase(command)) {
CompletableFuture.runAsync(() -> {
Integer paramRobotId = param.getInt("aid");
sleepTime(6000);
if (robotUser != null) {
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
//查询该房间的玩家信息
String playersStr = jedis0.hget(roomKey, "players");
if (!playersStr.equals("[]")) {
String players = playersStr.substring(1, playersStr.length() - 1);
String[] playerIds = players.split(",");
//判断只有当前机器人一个玩家
if (playerIds.length == 1) {
int playerId = Integer.parseInt(playerIds[0].trim());
if (playerId == paramRobotId) {
String gpid = jedis0.hget(roomKey, "gpid");
String gpId = jedis0.hget(roomKey, "group");
//发送退出房间协议
ITObject params = TObject.newInstance();
client.send("1005", params, response -> {
EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId));
//断开连接
disconnectFromGameServer(connecId);
//更新机器人剩余数量
updateLeftoverRobot(paramRobotId);
System.out.println("2009发送退出房间协议1005robotId: {"+paramRobotId+"}");
});
}
}
}
}
});
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
jedis0.close();
jedis2.close();
}
}
/**
* leftover_robot 退
*/
private void updateLeftoverRobot(int robotId) {
Jedis jedis2 = Redis.use("group1_db2").getJedis();
try {
jedis2.hset("gallrobot", String.valueOf(robotId), "0");
jedis2.hset("{grobot}:" + robotId, "start", "0");
System.out.println("机器人 {"+robotId+"} 退出房间修改gallrobot为0");
} finally {
jedis2.close();
}
}
/**
*
*/
public void login(RobotUser robotUser){
System.out.println("login:"+robotUser.getRobotId());
ITObject object = null;
AccountBusiness accountBusiness = null;
accountBusiness = new AccountBusiness();
try {
//先快速登录
object = accountBusiness.fastLogin(Integer.parseInt(robotUser.getRobotId()));
System.out.println("object:"+object);
if(object==null){
object = accountBusiness.idPasswordLogin(Integer.parseInt(robotUser.getRobotId()), robotUser.getPassword());
}
ITObject finalObject = object;
CompletableFuture.runAsync(() -> {
if (finalObject != null) {
//判断是否有房间
if(finalObject.getTObject("account")!=null){
ITObject validate = TObject.newInstance();
validate.putString("token", finalObject.getString("token"));
robotUser.setToken(finalObject.getString("token"));;
robotUser.setLoginsession("{user}:"+robotUser.getRobotId());
if (robotUser.getLoginsession() != null) {
robotUser.setIsLogin(true);
}
if(finalObject.getTObject("account").get("roomid")!=null){
String roomid = finalObject.getTObject("account").get("roomid").toString();
robotUser.setCurrentRoomId(Integer.parseInt(roomid));
connectGame(robotUser);
robotUser.setConnecId(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId());
System.err.println("重启获取的机器人还有当前房间,准备加入: "+robotUser.getConnecId());
exGameController.webGroupJoinRoom(robotUser);
}
}
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void connectGame(RobotUser robotUser){
if(robotUser.isLogin){
if(robotUser.getClient()==null){
TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "game", TaurusClient.ConnectionProtocol.Tcp);
client.setSession(robotUser.getLoginsession());
client.connect();
setupEventListeners(client, robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId());
robotUser.setIsconnect(client.isConnected());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
robotUser.setClient(client);
EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
}else{
System.out.println("reconnect");
System.out.println("client.isConnected()"+robotUser.getClient().isConnected());
if(robotUser.getClient().isConnected()){
robotUser.setIsconnect(true);
}else{
System.out.println("reconnect"+robotUser.getClient().getGameID());
TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "game", TaurusClient.ConnectionProtocol.Tcp);
client.setSession(robotUser.getLoginsession());
client.connect();
robotUser.setIsconnect(client.isConnected());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
robotUser.setClient(client);
EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
}
}
}
}
/**
*
*/
public void renconnect(RobotUser robotUser){
TaurusClient client = robotUser.getClient();
if(client!=null){
if(client.isConnected()){
client.connect();
robotUser.setIsconnect(client.isConnected());
}
}
}
/**
* connecId
*/
public TaurusClient getGameClient(String connecId) {
return robotRoomMapping.get(connecId) != null ? robotRoomMapping.get(connecId).getClient() : null;
}
public int getTime(){
return Integer.parseInt((System.currentTimeMillis() + "").substring(0, 10));
}
public static void sleepTime(int time) {
try {
//添加延迟
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,326 @@
package robot.mj;
import com.data.cache.BaseCache;
import com.data.cache.GroupCache;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.Map;
/**
* -
*/
public class RoomCreator {
private static final Logger log = LoggerFactory.getLogger(RoomCreator.class);
/**
* Redis
*
* @param groupId ID
* @param wanfaId ID
*/
public static RoomInfo createRoomInRedis(int groupId, int wanfaId, int robotId) {
try {
Jedis jedis0 = Redis.use("group1_db0").getJedis();
Jedis jedis11 = Redis.use("group1_db11").getJedis();
try {
//从free_room队列获取房间ID
String newRoomId = Redis.use("group1_db1").rpop("free_room");
if (StringUtil.isEmpty(newRoomId)) {
log.error("没有可用的房间IDfree_room队列为空");
return null;
}
//Redis.use("group1_db1").lpush("free_room", newRoomId);
String roomKey = "room:" + newRoomId;
//获取群组信息
String groupKey = "group:" + groupId;
Map<String, String> groupInfo = jedis11.hgetAll(groupKey);
//不存在则创建默认群组信息
if (groupInfo.isEmpty()) {
log.warn("群组信息不存在群组ID: {},正在创建默认群组信息", groupId);
createDefaultGroupInfo(jedis11, groupId);
groupInfo = jedis11.hgetAll(groupKey);
}
//确保游戏配置存在
String gameConfigKey = "game:" + wanfaId;
Map<String, String> gameInfo = jedis0.hgetAll(gameConfigKey);
//不存在则创建红中麻将的默认游戏配置
if (gameInfo.isEmpty()) {
log.warn("游戏配置不存在玩法ID: {},正在创建红中麻将默认游戏配置", wanfaId);
createDefaultGameConfig(jedis0, wanfaId);
gameInfo = jedis0.hgetAll(gameConfigKey);
}
//获取玩法配置
String playKey = "g{" + groupId + "}:play:" + wanfaId;
Map<String, String> playConfig = jedis11.hgetAll(playKey);
//不存在则创建红中麻将的默认玩法配置
if (playConfig.isEmpty()) {
log.warn("玩法配置不存在群组ID: {}, 玩法ID: {},正在创建红中麻将默认配置", groupId, wanfaId);
createDefaultChangshaMajiangConfig(jedis11, groupId, wanfaId);
playConfig = jedis11.hgetAll(playKey);
}
//构建房间信息
Map<String, String> roomMap = new HashMap<>();
//基础房间信息
roomMap.put("AA", "0"); //AA支付标志
roomMap.put("agent", "1"); //代理标志
roomMap.put("dismiss_time", "30"); //解散时间
roomMap.put("gpid", String.valueOf(wanfaId)); //玩法ID
roomMap.put("group", String.valueOf(groupId)); //群组ID
roomMap.put("hpOnOff", "1"); //体力开关
roomMap.put("hp_times", "1000"); //体力次数
roomMap.put("id", newRoomId); //房间ID
roomMap.put("kick_time", "30"); //踢出时间
roomMap.put("owner", "{user}:" + robotId); //房间所有者
roomMap.put("maxPlayers", "2"); //最大玩家数
roomMap.put("opt", "2"); //选项
roomMap.put("pay", "0"); //支付金额
roomMap.put("payer", String.valueOf(robotId)); //支付者ID
roomMap.put("rewardType", "0"); //奖励类型
roomMap.put("rewardValueType", "0"); //奖励值类型
roomMap.put("seats", "[1]"); //房间状态
roomMap.put("status", "0"); //房间状态
roomMap.put("times", "4"); //局数
roomMap.put("xipai_rewardType", "3"); //洗牌奖励类型
roomMap.put("xipai_rewardValueType", "1"); //洗牌奖励值类型
//如果有体力配置
String hpConfig = playConfig.get("hpConfig");
if (hpConfig != null) {
roomMap.put("limitInRoom", "1"); //房间内限制
}
//处理玩法选项配置
String playConfigJson = playConfig.getOrDefault("config", "{}");
ITObject configData = TObject.newFromJsonData(playConfigJson);
//原逻辑删除了字段
configData.del("opt");
configData.del("AA");
//将处理后的配置数据存储到options字段
roomMap.put("options", configData.toJson()); //选项配置
roomMap.put("game", String.valueOf(wanfaId)); //游戏ID
roomMap.put("open", "1"); //开放状态
roomMap.put("round", "0"); //回合数
roomMap.put("create_time", String.valueOf(System.currentTimeMillis() / 1000)); //创建时间
roomMap.put("cache_ver", "1"); //缓存版本
roomMap.put("players", "[]"); //玩家列表
roomMap.put("fake_existTime", "30"); //fake存在时间
//设置房间信息
jedis0.hmset(roomKey, roomMap);
//更新剩余机器人数量
String leftoverRobotStr = jedis11.hget(playKey, "leftover_robot");
int leftoverRobot = leftoverRobotStr != null ? Integer.parseInt(leftoverRobotStr) : 0;
if (leftoverRobot > 0) {
jedis11.hincrBy(playKey, "leftover_robot", -1);
}
//将房间添加到群组房间列表
String groomsKey = "g{" + groupId + "}:rooms";
jedis11.zadd(groomsKey, wanfaId * 10000 + 1101, roomKey);
//更新群组的缓存版本 确保客户端能够获取到最新的群组信息
String groupKeyForUpdate = GroupCache.genKey(groupId);
BaseCache.updateCacheVer(jedis11, groupKeyForUpdate);
//创建并返回房间信息
RoomInfo roomInfo = new RoomInfo();
roomInfo.setRoomId(roomKey);
roomInfo.setGroupId(groupId);
roomInfo.setWanfaId(wanfaId);
roomInfo.setServerIp("127.0.0.1");
roomInfo.setServerPort(getGamePortForWanfa(wanfaId));
log.info("成功创建机器人房间: {}, 群组: {}, 玩法: {}", roomKey, groupId, wanfaId);
return roomInfo;
} finally {
jedis0.close();
jedis11.close();
}
} catch (Exception e) {
log.error("创建房间时发生错误", e);
return null;
}
}
/**
* ID
*/
private static int getGamePortForWanfa(int wanfaId) {
switch (wanfaId) {
case 10: //红中麻将
return 6421;
default:
return 6421;
}
}
/**
*
*/
private static void createDefaultChangshaMajiangConfig(Jedis jedis11, int groupId, int wanfaId) {
try {
log.info("为群组 {} 和红中麻将玩法 {} 创建默认玩法配置", groupId, wanfaId);
String playKey = "g{" + groupId + "}:play:" + wanfaId;
Map<String, String> defaultConfig = new HashMap<>();
defaultConfig.put("opt", "1");
defaultConfig.put("groupId", String.valueOf(groupId));
defaultConfig.put("id", String.valueOf(wanfaId));
defaultConfig.put("gameId", String.valueOf(wanfaId));
defaultConfig.put("name", "红中麻将-机器人专用");
defaultConfig.put("deskId", "0");
defaultConfig.put("maxPlayers", "4");
defaultConfig.put("hpOnOff", "0");
defaultConfig.put("rewardType", "0");
defaultConfig.put("rewardValueType", "0");
defaultConfig.put("xipai_rewardType", "0");
defaultConfig.put("xipai_rewardValueType", "0");
defaultConfig.put("hp_times", "0");
defaultConfig.put("ban", "0");
defaultConfig.put("robot_room", "1");
defaultConfig.put("shangxian_robot", "10"); //限制机器人数量
defaultConfig.put("leftover_robot", "10"); //设置剩余机器人数量
defaultConfig.put("reward", "0");
defaultConfig.put("xipai_reward", "100");
defaultConfig.put("anchou_reward", "1");
defaultConfig.put("mark", "0");
defaultConfig.put("cache_ver", "1");
//红中麻将配置选项
defaultConfig.put("config", "{\"maxPlayers\":4,\"pid\":22,\"opt\":1,\"AA\":0,\"maxRound\":8,\"dianpao\":1,\"zimo\":1,\"haidi\":1,\"ting\":1,\"piao\":0,\"chongfeng\":1,\"queyimen\":0,\"hujia\":0,\"hongzhong\":1,\"qgh\":0,\"qgh_opt\":0,\"qgh_type\":0,\"qgh_score\":0,\"qgh_double\":0,\"qgh_double_opt\":0,\"qgh_double_type\":0,\"qgh_double_score\":0,\"qgh_double_score_opt\":0,\"qgh_double_score_type\":0,\"qgh_double_score_type_opt\":0}");
defaultConfig.put("hpConfig", "{\"times\":1,\"limitInRoom\":0,\"maxRound\":8}");
jedis11.hmset(playKey, defaultConfig);
//更新缓存版本
jedis11.hincrBy(playKey, "cache_ver", 1);
//更新群组玩法列表 将此玩法添加进去
String gpidsKey = "g{" + groupId + "}:pids";
jedis11.zadd(gpidsKey, 1 * 10 + 0, String.valueOf(wanfaId));
log.info("成功创建红中麻将默认玩法配置 键名: {}", playKey);
} catch (Exception e) {
log.error("创建红中麻将默认玩法配置时发生错误 群组ID: {}, 玩法ID: {}", groupId, wanfaId, e);
}
}
/**
*
*/
private static void createDefaultGroupInfo(Jedis jedis11, int groupId) {
try {
log.info("为群组 {} 创建默认群组信息", groupId);
String groupKey = "group:" + groupId;
Map<String, String> defaultGroupInfo = new HashMap<>();
defaultGroupInfo.put("ban", "0"); //未禁用
defaultGroupInfo.put("ban_apply", "0"); //不禁止申请
defaultGroupInfo.put("ban_chat1", "false");
defaultGroupInfo.put("ban_chat2", "false");
defaultGroupInfo.put("create_time", String.valueOf(System.currentTimeMillis() / 1000));
defaultGroupInfo.put("dissolve_opt", "1"); //解散选项
defaultGroupInfo.put("exit_opt", "0");
defaultGroupInfo.put("gms", "19");
defaultGroupInfo.put("id", String.valueOf(groupId));
defaultGroupInfo.put("kick_opt", "1"); //踢人选项
defaultGroupInfo.put("name", "机器人专用群组-" + groupId);
defaultGroupInfo.put("notice", "");
defaultGroupInfo.put("opt", "1"); //开启状态
defaultGroupInfo.put("option", "0"); //选项
defaultGroupInfo.put("owner", "999999"); //使用机器人系统账户ID
defaultGroupInfo.put("pay_type", "1"); //房主支付
defaultGroupInfo.put("type", "2"); //普通群组类型
jedis11.hmset(groupKey, defaultGroupInfo);
log.info("成功创建默认群组信息,键名: {}", groupKey);
} catch (Exception e) {
log.error("创建默认群组信息时发生错误群组ID: {}", groupId, e);
}
}
/**
*
*/
private static void createDefaultGameConfig(Jedis jedis0, int wanfaId) {
try {
log.info("为玩法 {} 创建默认游戏配置", wanfaId);
String gameConfigKey = "game:" + wanfaId;
Map<String, String> defaultGameInfo = new HashMap<>();
defaultGameInfo.put("id", String.valueOf(wanfaId));
defaultGameInfo.put("name", "红中麻将");
defaultGameInfo.put("maxPlayers", "4"); //红中麻将为4人游戏
defaultGameInfo.put("minPlayers", "2"); //最少2人
defaultGameInfo.put("type", "1"); //游戏类型
defaultGameInfo.put("status", "1"); //状态开启
defaultGameInfo.put("icon", ""); //图标
defaultGameInfo.put("desc", "红中麻将游戏"); //描述
defaultGameInfo.put("version", "1.0"); //版本
defaultGameInfo.put("pay", "0"); //支付金额
defaultGameInfo.put("times", "8"); //局数
defaultGameInfo.put("hpType", "0"); // 体力值类型,必需字段
defaultGameInfo.put("gameType", "1"); // 游戏类型,必需字段
defaultGameInfo.put("isNonnegative", "0"); // 不可负分,必需字段
defaultGameInfo.put("opt1", "8");
defaultGameInfo.put("opt2", "16");
defaultGameInfo.put("opt3", "24");
defaultGameInfo.put("opt4", "32");
defaultGameInfo.put("opt5", "40");
//设置支付选项
defaultGameInfo.put("pay1_2", "10");
defaultGameInfo.put("pay1_3", "15");
defaultGameInfo.put("pay1_4", "20");
jedis0.hmset(gameConfigKey, defaultGameInfo);
log.info("成功创建默认游戏配置,键名: {}", gameConfigKey);
} catch (Exception e) {
log.error("创建默认游戏配置时发生错误玩法ID: {}", wanfaId, e);
}
}
/**
*
*/
public static class RoomInfo {
private String roomId;
private int groupId;
private int wanfaId;
private String serverIp;
private int serverPort;
public String getRoomId() { return roomId; }
public void setRoomId(String roomId) { this.roomId = roomId; }
public int getGroupId() { return groupId; }
public void setGroupId(int groupId) { this.groupId = groupId; }
public int getWanfaId() { return wanfaId; }
public void setWanfaId(int wanfaId) { this.wanfaId = wanfaId; }
public String getServerIp() { return serverIp; }
public void setServerIp(String serverIp) { this.serverIp = serverIp; }
public int getServerPort() { return serverPort; }
public void setServerPort(int serverPort) { this.serverPort = serverPort; }
}
}

View File

@ -0,0 +1,380 @@
package robot.mj.business;
import com.data.bean.AccountBean;
import com.data.bean.GameBean;
import com.data.cache.AccountCache;
import com.data.cache.BaseCache;
import com.data.cache.GameCache;
import com.data.util.ErrorCode;
import com.data.util.Utility;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.database.DataBase;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.plugin.redis.RedisLock;
import com.taurus.core.util.Logger;
import com.taurus.core.util.StringUtil;
import com.taurus.core.util.Utils;
import com.taurus.web.Controller;
import com.taurus.web.WebException;
import redis.clients.jedis.Jedis;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class AccountBusiness extends Controller {
private static Logger logger = Logger.getLogger(AccountBusiness.class);
public static String request(String httpUrl, String httpArg) {
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?" + httpArg;
try {
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = reader.readLine();
if (strRead != null) {
sbf.append(strRead);
while ((strRead = reader.readLine()) != null) {
sbf.append("\n");
sbf.append(strRead);
}
}
reader.close();
result = sbf.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String md5(String plainText) {
StringBuffer buf = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return buf.toString();
}
public static String encodeUrlString(String str, String charset) {
String strret = null;
if (str == null)
return str;
try {
strret = java.net.URLEncoder.encode(str, charset);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return strret;
}
private final ITObject fillLoginData(String session, int accountid) {
ITObject resData = TObject.newInstance();
ITObject userData = TObject.newInstance();
resData.putTObject("account", userData);
resData.putUtfString("session_id", session);
resData.putTArray("games", getOnlineGames());
Jedis jedis0 = Redis.use("group1_db0").getJedis();
try {
Map<String, String> map = jedis0.hgetAll(session);
userData.putInt("id", accountid);
userData.putInt("diamo", Integer.parseInt(map.get("diamo")));
userData.putUtfString("nick", map.get("nick"));
userData.putUtfString("portrait", map.get("portrait"));
userData.putInt("sex", Integer.parseInt(map.get("sex")));
userData.putInt("type", Integer.parseInt(map.get("type")));
int mng = Integer.parseInt(map.get("mng"));
userData.putInt("mng", mng);
String phone = map.get("phone");
if (StringUtil.isNotEmpty(phone)) {
userData.putUtfString("phone", phone);
}
String address = map.get("address");
if (StringUtil.isNotEmpty(address)) {
userData.putUtfString("address", address);
}
String real_info = map.get("real_info");
if (StringUtil.isNotEmpty(real_info)) {
userData.putTObject("real_info", TObject.newFromJsonData(real_info));
}
String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, accountid);
if (StringUtil.isNotEmpty(oldRoom)) {
String roomid = oldRoom.replace("room:", "");
String group = jedis0.hget(oldRoom, "group");
int groupId = 0;
if (StringUtil.isNotEmpty(group)) {
groupId = Integer.parseInt(group);
}
userData.putUtfString("roomid", roomid);
userData.putInt("groupId", groupId);
}
} finally {
jedis0.close();
}
resData.putUtfString("groupWeb", Redis.use("group1_db1").hget("web_requrl", "groupWeb_jefe"));
return resData;
}
public final ITObject fastLogin(int userid) throws Exception {
Jedis jedis = Redis.use("group1_db0").getJedis();
ITObject resData = null;
try {
Set<String> usertoken = jedis.smembers("{user}:"+userid+"_token");
if (usertoken.size()<=0){
return null;
}
String token = "";
for (String item : usertoken) {
token = item;
}
String session ="{user}:"+userid;
AccountBean acc_bean = AccountCache.getAccount(session);
resData = fillLoginData(session, acc_bean.id);
String idPwdBan = Redis.use("group1_db0").get(acc_bean.id+"_login_ban");
if (StringUtil.isNotEmpty(idPwdBan))
{
logger.error("id:"+acc_bean.id+" ban login");
throw new WebException(ErrorCode.BAN_LOGIN);
}
resData.putString("token", token);
return resData;
}catch (Exception e){
}finally {
jedis.close();
}
return resData;
}
public final ITObject idPasswordLogin(int id, String password) throws Exception {
logger.info("id:" + id + " login");
Jedis jedis0 = Redis.use("group1_db0").getJedis();
RedisLock lock = new RedisLock("wx_" + id, jedis0);
try {
logger.info("==========> password111 = " + password);
String superPwd = Redis.use("group1_db1").get("superpwd2021");
String sql = "";
if (!StringUtil.isEmpty(superPwd)) {
if (!password.equals(superPwd)) {
password = Utils.getMD5Hash(password);
sql = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'", id, password);
} else {
logger.info("==========> password = " + password);
sql = String.format("SELECT * FROM account WHERE id ='%d' ", id);
}
} else {
password = Utils.getMD5Hash(password);
sql = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'", id, password);
}
String idPwdBan = Redis.use("group1_db0").get(id + "_login_ban");
if (StringUtil.isNotEmpty(idPwdBan)) {
System.out.println("进入了77777777777777777777");
logger.error("id:" + id + " ban login");
throw new WebException(ErrorCode.BAN_LOGIN);
}
System.out.println("进入了9999999999999");
ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
if (resultArray.size() == 0) {
if (Redis.use("group1_db0").exists(id + "_pwd_token")) {
Redis.use("group1_db0").incrBy(id + "_pwd_token", 1);
} else {
Redis.use("group1_db0").set(id + "_pwd_token", 1 + "");
Redis.use("group1_db0").expire(id + "_pwd_token", 300);
}
String idPwdToken = Redis.use("group1_db0").get(id + "_pwd_token");
if (StringUtil.isNotEmpty(idPwdToken)) {
long count = Long.parseLong(idPwdToken);
if (count >= 10) {
Redis.use("group1_db0").set(id + "_login_ban", "1");
Redis.use("group1_db0").expire(id + "_login_ban", 1800);
logger.error("pwd error count:" + count + " not login");
System.out.println("进入了00000000000");
throw new WebException(ErrorCode._NO_SESSION);
}
}
System.out.println("进入了111111111111");
throw new WebException(ErrorCode._FAILED);
}
ITObject userData = resultArray.getTObject(0);
int accountid = userData.getInt("id");
UpdateUserData(userData, accountid);
AccountBean acc_bean = AccountCache.getAccount(accountid);
String session = acc_bean.redis_key;
this.setSession(session);
if (resultArray.size() > 0) {
this.setSession(session);
String old_nick = acc_bean.nick;
String old_portrait = acc_bean.portrait;
// String new_nick = reqData.getUtfString("nick");
// String new_portrait = reqData.getUtfString("portrait");
// if (!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) {
// ITObject userData1 = TObject.newInstance();
// userData1.putUtfString("nick", userData.getUtfString("nick"));
// userData1.putUtfString("portrait", userData.getUtfString("portrait"));
// userData1.putInt("sex", userData.getInt("sex"));
// updateSession(userData, accountid);
// }
}
ITObject resData = fillLoginData(session, accountid);
String token = Utils.getMD5Hash(id + "_" + password + "_" + System.currentTimeMillis() + "e4!Fesu]]{QyUuEA"
+ Math.random() * 1000000);
Redis.use("group1_db0").sadd(session + "_token", token);
Redis.use("group1_db0").hset(token, "user", session);
Redis.use("group1_db0").hset(token, "create_time", "" + System.currentTimeMillis() / 1000);
Redis.use("group1_db0").expire(token, 172800);
// Set<String> allToken = Redis.use("group1_db0").smembers(session + "_token");
// for (String temp : allToken) {
// if (!Redis.use("group1_db0").exists(temp)) {
// Redis.use("group1_db0").srem(session + "_token", temp);
// logger.info("delte timeout token:" + temp);
// }
// }
System.out.println("进入了2222222222222");
long tokenNum = Redis.use("group1_db0").scard(session + "_token");
if (tokenNum >= 10) {
logger.warn("id:" + accountid + " repeat login, token count:" + tokenNum);
}
System.out.println("进入了33333333333333333332");
resData.putString("token", token);
return resData;
} finally {
lock.unlock();
}
}
private static String updateSession(ITObject userData, int id) {
String session = AccountCache.genKey(id);
Map<String, String> map = new HashMap<String, String>();
Utils.objectToMap(userData, map);
Jedis jedis0 = Redis.use("group1_db0").getJedis();
try {
jedis0.hmset(session, map);
BaseCache.updateCacheVer(jedis0, session);
} finally {
jedis0.close();
}
return session;
}
/**
* 线
*/
public static ITArray getOnlineGames() {
ITArray games = new TArray();
Jedis jedis1 = Redis.use("group1_db1").getJedis();
try {
Set<String> list = jedis1.zrevrangeByScore("online_games", 1000, 1);
for (String game : list) {
int gameId = Integer.parseInt(game);
GameBean gb = GameCache.getGame(gameId);
if (gb == null)
continue;
ITObject gameObj = gb.getTObject();
for (Entry<String, Integer> entry : gb.pay.entrySet()) {
gameObj.putInt(entry.getKey(), entry.getValue());
}
games.addTObject(gameObj);
}
} finally {
jedis1.close();
}
return games;
}
/**
*
* @return
* @throws Exception
*/
private final int UpdateUserData(ITObject reqData, long id) throws Exception {
ITObject userData = TObject.newInstance();
userData.putInt("id", (int) id);
userData.putUtfString("acc", reqData.getUtfString("acc"));
userData.putUtfString("portrait", reqData.getUtfString("portrait"));
userData.putUtfString("nick", reqData.getUtfString("nick"));
int sex = reqData.getInt("sex");
if (sex == 0) {
sex = 1;
reqData.putInt("sex", sex);
}
userData.putInt("sex", sex);
userData.putInt("mng", 0);
userData.putInt("type", 0);
if (reqData.containsKey("diamo")) {
userData.putInt("diamo", reqData.getInt("diamo"));
}
userData.putInt("invitation", 1);
String session = updateSession(userData, (int) id);
this.setSession(session);
return (int) id;
}
}

View File

@ -0,0 +1,443 @@
package robot.mj.handler;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.StringUtil;
import redis.clients.jedis.Jedis;
import taurus.client.Message;
import taurus.client.TaurusClient;
import taurus.util.CardUtil;
import taurus.util.HongZhongSuanFaTest;
import taurus.util.Util;
import java.util.*;
public class HuNanHongZhong {
public static int hongZhongCard = 0;
//红中麻将手牌
private final List<Integer> hongZhongCardInhand = new ArrayList<>();
//红中麻将出过的牌
private final List<Integer> hongZhongchuguopai = new ArrayList<>();
// 玩家座位号
public static int seat = 0;
public static int playerId = 0;
// 会话标识
public static String session = "";
// 访问令牌
public static String token = "";
//红中麻将算法
// private static HongZhongSuanFa hongZhongSuanFa = new HongZhongSuanFa();
private static HongZhongSuanFaTest hongZhongSuanFaTest = new HongZhongSuanFaTest();
private static final Gson gson = new Gson();
// 公共的getter和setter方法
public List<Integer> getHongZhongCardInhand() {
return hongZhongCardInhand;
}
public List<Integer> getChuGuoCardInhand() {
return hongZhongchuguopai;
}
/**
* JSONRedis
* @param connecId ID
*/
public void saveToRedis(String connecId) {
Jedis jedis = Redis.use("group1_db2").getJedis();
try {
Map<String, String> stateMap = new HashMap<>();
stateMap.put("hongZhongCardInhand", gson.toJson(hongZhongCardInhand));
stateMap.put("hongZhongchuguopai", gson.toJson(hongZhongchuguopai));
stateMap.put("session", session);
stateMap.put("token", token);
String redisKey = "{hzmj}:" + connecId;
jedis.hmset(redisKey, stateMap);
//1小时过期时间
jedis.expire(redisKey, 3600);
System.out.println("保存HuNanHongZhong状态到Redis: " + connecId);
} catch (Exception e) {
System.err.println("保存HuNanHongZhong状态到Redis失败: " + e.getMessage());
} finally {
jedis.close();
}
}
/**
* Redis
* @param connecId ID
* @return
*/
public boolean restoreFromRedis(String connecId) {
Jedis jedis = Redis.use("group1_db2").getJedis();
try {
String redisKey = "{hzmj}:" + connecId;
Map<String, String> stateMap = jedis.hgetAll(redisKey);
if (stateMap == null || stateMap.isEmpty()) {
System.out.println("Redis中没有找到HuNanHongZhong状态数据: " + connecId);
return false;
}
//反序列化集合
if (stateMap.containsKey("hongZhongCardInhand")) {
hongZhongCardInhand.clear();
List<Integer> handCards = gson.fromJson(stateMap.get("hongZhongCardInhand"),
new TypeToken<List<Integer>>(){}.getType());
if (handCards != null) hongZhongCardInhand.addAll(handCards);
}
if (stateMap.containsKey("hongZhongchuguopai")) {
hongZhongchuguopai.clear();
List<Integer> handCards = gson.fromJson(stateMap.get("hongZhongchuguopai"),
new TypeToken<List<Integer>>(){}.getType());
if (handCards != null) hongZhongchuguopai.addAll(handCards);
}
session = stateMap.getOrDefault("session", "");
token = stateMap.getOrDefault("token", "");
System.out.println("从Redis恢复HuNanHongZhong状态成功: " + connecId + ", 手牌数量: " + hongZhongchuguopai.size());
return true;
} catch (Exception e) {
System.err.println("从Redis恢复HuNanHongZhong状态失败: " + e.getMessage());
return false;
} finally {
jedis.close();
}
}
/**
* Redis
* @param connecId ID
*/
public static void removeFromRedis(String connecId) {
Jedis jedis = Redis.use("group1_db2").getJedis();
try {
String redisKey = "{hzmj}:" + connecId;
jedis.del(redisKey);
System.out.println("从Redis删除HuNanHongZhong状态: " + connecId);
} catch (Exception e) {
System.err.println("从Redis删除HuNanHongZhong状态失败: " + e.getMessage());
} finally {
jedis.close();
}
}
/**
*
* @param handCard
*/
public void updateHandCard(List<Integer> handCard) {
System.out.println("updateHandCard同步手牌:"+ handCard);
hongZhongCardInhand.clear();
System.out.println("updateHandCard同步手牌hongZhongCardInhand:"+ hongZhongCardInhand);
hongZhongCardInhand.addAll(handCard);
System.out.println("updateHandCard同步手牌add:"+ hongZhongCardInhand);
}
public void updateOutCard(List<Integer> outCard) {
hongZhongchuguopai.clear();
hongZhongchuguopai.addAll(outCard);
}
/**
* 广 812
*
* @param command
* @param message
* @return
*/
public String drawCard(String command, Message message) {
if (command.equalsIgnoreCase("812")) {
ITObject param = message.param;
if (param == null) {
return null;
}
hongZhongCard = param.getInt("card");
System.out.println("出牌广播" + hongZhongCard);
System.out.println("座位号:" + param.getInt("seat") + "的用户出牌:" + param.getInt("card"));
}
return null;
}
/**
* 819
*
* @param command
* @param message
* @return
*/
public String getCard(String command, Message message) {
System.out.println("摸牌协议-----" + command + "message---" + message);
if (command.equalsIgnoreCase("819")) {
ITObject param = message.param;
if (param == null) {
return null;
}
// {seat=2, Ishupai=0, isBaoTing=-1, tingcard=0, isgang=0, card=101, left_count=106}
System.out.println("轮到用户:" + param.getInt("player") + "的用户摸牌" + ",牌为:" + param.getInt("card"));
System.out.println("用户id" + playerId);
System.out.println("座位号" + param.getInt("seat"));
if (param.getInt("player") != null) {
int drawnCard = param.getInt("card");
hongZhongSuanFaTest.drawnCards = drawnCard;
hongZhongCardInhand.add(drawnCard);
System.out.println("摸牌后手牌" + hongZhongCardInhand);
// 创建包含摸牌后的完整手牌
List<Integer> newHand = new ArrayList<>(hongZhongCardInhand);
// 调用分离分析方法,将刻子、顺子、红中单独拎出后分析剩余牌
System.out.println("[HuNanHongZhong] 开始分离分析手牌结构...");
hongZhongSuanFaTest.separateAndAnalyzeHand(newHand);
// 直接调用hongZhongSuanFaTest中的analyzeDrawCard方法分析摸牌后是否可听牌
hongZhongSuanFaTest.analyzeDrawCard(hongZhongCardInhand, drawnCard);
// 调用新添加的findDiscardToTing方法分析打出哪张牌可以听牌
System.out.println("[HuNanHongZhong] 开始分析打出哪张牌可以听牌...");
Map<Integer, Set<Integer>> discardOptions = hongZhongSuanFaTest.findDiscardToTing(newHand);
// 如果有可打出后听牌的选项,记录信息
if (!discardOptions.isEmpty()) {
System.out.println("[HuNanHongZhong] 发现" + discardOptions.size() + "个可打出后听牌的选项");
// 这些信息将在出牌决策时被考虑
} else {
System.out.println("[HuNanHongZhong] 当前没有可以打出后听牌的牌");
}
}
}
return null;
}
/**
*
*
* @param proposedCard
* @return
*/
public boolean shouldPong(int proposedCard) {
System.out.println("判断是否应该碰牌: " + proposedCard);
// 直接调用hongZhongSuanFaTest中的shouldPong方法它已经包含了所有需要的规则
return hongZhongSuanFaTest.shouldPong(proposedCard, hongZhongCardInhand);
// return hongZhongSuanFaTest.shouldPong(proposedCard, Arrays.asList(305,304,303,207,207,204,204,208,208,201,201,412,412));
}
/**
* 811
*
* @param command
* @param message
* @return
*/
public String cardInHead(String command, Message message, TaurusClient client) {
if (command.equalsIgnoreCase("811")) {
ITObject param = message.param;
if (param == null) {
return null;
}
// {bank_seat=1, laiziCard=0, laiziCard2=0, laiziCard2Before=0, jing=0, laiziCardBefore=0, card_list=[101, 103, 104, 201, 204, 207, 208, 209, 307, 309, 501, 502, 503]}
ITArray cardList = param.getTArray("card_list");
for (int i = 0; i < cardList.size(); i++) {
hongZhongCardInhand.add(cardList.getInt(i));
}
if (hongZhongCardInhand.size() > 13) {
outCard(client);
System.out.println("机器人:" + param.getInt("seat") + "为庄家,需要出牌" + ",牌为:" + hongZhongCardInhand.get(0));
}
System.out.println("机器人:" + param.getInt("seat") + "初始化手牌" + ",牌为:" + hongZhongCardInhand.toString());
}
return null;
}
/**
*
*
* @param param
* @return
*/
public String actionCard(ITObject param, TaurusClient client) {
//获取碰杠胡参数 type 和id 后续算法接入,是否能让碰和杠
ITArray tipList = param.getTArray("tip_list");
int id = 0;
int type = 0;
int opcard = 0;
ITObject params = TObject.newInstance();
if (tipList != null && tipList.size() > 0) {
TObject firstTip = (TObject) tipList.get(0).getObject();
id = firstTip.getInt("id");
type = firstTip.getInt("type");
opcard = firstTip.getTArray("opcard").getInt(0);
System.out.println("id ++ " + id);
System.out.println("type ++ " + type);
}
//弃 是根据算法选择是否要弃掉 不进行碰杠胡
//params.putInt("qi", 0);
//params.putInt("id", 0);
//执行碰牌
if (type == 2) {
// 根据规则判断是否应该碰牌
if (shouldPong(opcard)) {
params.putString("session", session + "," + token);
params.putInt("qi", 0);
params.putInt("id", 1);
Util.removeCard(hongZhongCardInhand, opcard, 2);
System.out.println("执行碰牌并删除碰的牌");
} else {
params.putString("session", session + "," + token);
params.putInt("qi", 1); // 放弃碰牌
params.putInt("id", 0);
System.out.println("根据规则,决定不碰牌: " + opcard);
}
// Global.logger.info("删除碰的牌");
//执行胡牌
} else if (type == 6) {
params.putString("session", session + "," + token);
params.putInt("qi", 0);
params.putInt("id", 1);
System.out.println("执行胡牌");
//执行吃杠
} else if (type == 3) {
params.putString("session", session + "," + token);
params.putInt("qi", 0);
params.putInt("id", 1);
Util.removeCard(hongZhongCardInhand, opcard, 3);
System.out.println("执行吃杠");
//执行自杠
} else if (type == 4) {
params.putString("session", session + "," + token);
params.putInt("qi", 0);
params.putInt("id", 1);
Util.removeCard(hongZhongCardInhand, opcard, 4);
System.out.println("执行自杠");
// 碰后补杠
} else if (type == 5) {
params.putString("session", session + "," + token);
params.putInt("qi", 0);
params.putInt("id", 1);
Util.removeCard(hongZhongCardInhand, opcard, 1);
System.out.println("执行碰后补杠");
}
// cardInhand.remove(0);
// cardInhand.remove(1);
System.out.println("执行id为" + 0 + "的操作");
client.send("612", params, response -> {
System.out.println("操作成功: " + response.returnCode);
});
return null;
}
public static String changePlayer(String command, Message message) {
if (command.equalsIgnoreCase("820")) {
ITObject param = message.param;
if (param == null) {
return null;
}
System.out.println("出牌权转移到座位号:" + param.getInt("seat") + "的用户");
}
return null;
}
/**
*
*/
// public String outCard(TaurusClient client, List< Integer> list) {
public String outCard(TaurusClient client) {
// 调用分离分析方法,将刻子、顺子、红中单独拎出后分析剩余牌
System.out.println("[HuNanHongZhong] 出牌前分离分析手牌结构...");
hongZhongSuanFaTest.separateAndAnalyzeHand(hongZhongCardInhand);
// 红中麻将出牌
String hongzhongOutCard = hongZhongSuanFaTest.outCardSuanFa(hongZhongCardInhand, hongZhongCard);
// String hongzhongOutCard = hongZhongSuanFaTest.outCardSuanFa(list, hongZhongCard);
ITObject params = TObject.newInstance();
int cardToOut;
if (StringUtil.isNotEmpty(hongzhongOutCard)) {
cardToOut = Integer.parseInt(hongzhongOutCard);
} else {
cardToOut = hongZhongCardInhand.get(0);
}
params.putInt("card", cardToOut);
int outCountBefore = hongZhongchuguopai.size(); // 当前历史出牌数量
// 第n次出牌时发送前n-1张出牌
if (outCountBefore >= 1) {
// 发送前n-1张所有历史出牌
List<Integer> cardsToSend = hongZhongchuguopai.subList(0, outCountBefore);
params.putTArray("outcard_list", CardUtil.maJiangToTArray(cardsToSend));
}
params.putTArray("card_list", CardUtil.maJiangToTArray(hongZhongCardInhand));
System.out.println("机器人牌============" + params);
// 将当前出的牌添加到历史出牌列表
hongZhongchuguopai.add(cardToOut);
// 从手牌中移除
hongZhongCardInhand.remove(Integer.valueOf(cardToOut));
System.out.println("出牌: " + cardToOut);
System.out.println("目前机器人剩余手牌:" + hongZhongCardInhand.toString());
params.putString("session", session + "," + token);
client.send("611", params, response -> {
System.out.println("出牌成功: " + response.returnCode);
});
return null;
}
/**
*
*
* @param param
* @return
*/
public String shanchuchuguopai(ITObject param) {
if (param == null) {
return null;
}
Integer card = param.getInt("card"); // 操作牌值
Integer type = param.getInt("type"); // 操作类型
Integer from_seat = param.getInt("from_seat"); // 牌来源座位
System.out.println("删除出过的牌组 card " + card);
System.out.println("删除出过的牌组 type " + type);
System.out.println("删除出过的牌组 from_seat " + from_seat);
System.out.println("机器人 seat " + seat);
if (type == 2 || type == 3 || type == 5) { // 碰,杠
getChuGuoCardInhand().remove(Integer.valueOf(card));
System.out.println("删除出过的牌组 成功");
}
return null;
}
}

View File

@ -0,0 +1,164 @@
package robot.mj.info;
import taurus.client.TaurusClient;
/**
*
*/
public class RobotUser {
private String connecId;
private int userId;
private String robotId;
private int seat;
public int status; //工作状态 0,1:等待2:干活
public boolean isconnect = false; //是否连接上
public int intoRoomTime; //进入房间时间戳
public String password;
public String gameHost;
public String gamePort;
public String robotGroupid;
public String robotPid;
public boolean isLogin = false;
private String token;
private String loginsession;
public int currentRoomId;//当前房间id
public TaurusClient client = null;
public TaurusClient getClient() {
return client;
}
public void setClient(TaurusClient client) {
this.client = client;
}
public int getCurrentRoomId() {
return currentRoomId;
}
public void setCurrentRoomId(int currentRoomId) {
this.currentRoomId = currentRoomId;
}
public String getLoginsession() {
return loginsession;
}
public void setLoginsession(String loginsession) {
this.loginsession = loginsession;
}
public boolean getIsLogin() {
return isLogin;
}
public void setIsLogin(boolean login) {
isLogin = login;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getGameHost() {
return gameHost;
}
public void setGameHost(String gameHost) {
this.gameHost = gameHost;
}
public String getGamePort() {
return gamePort;
}
public void setGamePort(String gamePort) {
this.gamePort = gamePort;
}
public String getRobotGroupid() {
return robotGroupid;
}
public void setRobotGroupid(String robotGroupid) {
this.robotGroupid = robotGroupid;
}
public String getRobotPid() {
return robotPid;
}
public void setRobotPid(String robotPid) {
this.robotPid = robotPid;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getIntoRoomTime() {
return intoRoomTime;
}
public void setIntoRoomTime(int intoRoomTime) {
this.intoRoomTime = intoRoomTime;
}
public boolean getIsconnect() {
return isconnect;
}
public void setIsconnect(boolean isconnect) {
this.isconnect = isconnect;
}
public int getSeat() {
return seat;
}
public void setSeat(int seat) {
this.seat = seat;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getConnecId() {
return connecId;
}
public void setConnecId(String connecId) {
this.connecId = connecId;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getRobotId() {
return robotId;
}
public void setRobotId(String robotId) {
this.robotId = robotId;
}
}

View File

@ -0,0 +1,378 @@
package taurus.util;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.TArray;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CardUtil {
/**
*
*
* @param handCards
* @return null
*/
public static CardObj findMaxSingleCard(List<CardObj> handCards) {
if (handCards == null || handCards.isEmpty()) {
return null;
}
handCards.sort((c1, c2) -> c2.cardMod - c1.cardMod);
return handCards.get(0);
}
/**
* list to TArray
*
* @param list
* @return
*/
public static final ITArray toTArray(List<CardObj> list) {
ITArray result = new TArray();
for (CardObj card : list) {
result.addInt(card.card);
}
return result;
}
public static final ITArray toTArray1(CardObj list) {
ITArray result = new TArray();
result.addInt(list.card);
return result;
}
public static final ITArray maJiangToTArray(List<Integer> list) {
ITArray result = new TArray();
for (Integer integer : list) {
result.addInt(integer);
}
return result;
}
public static final CardObj getCard(int eventCard, List<CardObj> cardList) {
for (CardObj card : cardList) {
if (card.cardMod == eventCard) {
return card;
}
}
return null;
}
public static final CardObj getCard1(int eventCard, List<CardObj> cardList) {
for (CardObj card : cardList) {
if (card.card == eventCard) {
return card;
}
}
return null;
}
/**
*
*
* @param eventCard
* @param cardList
* @param num
* @return
*/
public static final boolean checkCard(int eventCard, List<CardObj> cardList, int num) {
int result = 0;
for (CardObj card : cardList) {
if (card.cardMod == eventCard) {
result++;
if (result == num)
return true;
}
}
return false;
}
public static final boolean checkGoodCard(int eventCard, List<CardObj> cardList, int num) {
int result = 0;
for (CardObj card : cardList) {
if (card.cardMod == eventCard) {
result++;
if (result >= num)
return true;
}
}
return false;
}
public static final boolean checkShunZi(int eventCard, List<CardObj> cardList) {
int result = 0;
if (checkGoodCard(eventCard + 1, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 2, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 3, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 4, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 5, cardList, 1)) {
result++;
}
}
}
}
}
if (checkGoodCard(eventCard - 1, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 2, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 3, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 4, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 5, cardList, 1)) {
result++;
}
}
}
}
}
if (result >= 4) {
return true;
}
return false;
}
public static final boolean checkSevenShunzi(int eventCard, List<CardObj> cardList) {
int result = 0;
if (checkGoodCard(eventCard + 1, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 2, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 3, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 4, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 5, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 6, cardList, 1)) {
result++;
if (checkGoodCard(eventCard + 7, cardList, 1)) {
result++;
}
}
}
}
}
}
}
if (checkGoodCard(eventCard - 1, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 2, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 3, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 4, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 5, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 6, cardList, 1)) {
result++;
if (checkGoodCard(eventCard - 7, cardList, 1)) {
result++;
}
}
}
}
}
}
}
if (result >= 6) {
return true;
}
return false;
}
public static final boolean checkFenJi(int eventCard, List<CardObj> cardList) {
int result = 0;
if (checkGoodCard(eventCard, cardList, 2)) {
result++;
if (checkGoodCard(eventCard + 1, cardList, 3)) {
result++;
}
if (checkGoodCard(eventCard - 1, cardList, 3)) {
result++;
}
}
if (result >= 2) {
return true;
}
return false;
}
public static final boolean checkFourDui(int eventCard, List<CardObj> cardList) {
int result = 0;
if (checkGoodCard(eventCard, cardList, 1)) {
result++;
}
if (checkGoodCard(eventCard + 1, cardList, 2)) {
result++;
if (checkGoodCard(eventCard + 2, cardList, 2)) {
result++;
if (checkGoodCard(eventCard + 3, cardList, 2)) {
result++;
if (checkGoodCard(eventCard + 4, cardList, 2)) {
result++;
}
}
}
}
if (checkGoodCard(eventCard - 1, cardList, 2)) {
result++;
if (checkGoodCard(eventCard - 2, cardList, 2)) {
result++;
if (checkGoodCard(eventCard - 3, cardList, 2)) {
result++;
if (checkGoodCard(eventCard - 4, cardList, 2)) {
result++;
}
}
}
}
if (result >= 4) {
return true;
}
return false;
}
public static final boolean checkQPai(int eventCard, List<CardObj> cardList) {
int result = 0;
if (eventCard >= 12) {
result++;
for (CardObj card : cardList) {
if (card.cardMod >= 12) {
result++;
}
}
}
if (result >= 5) {
return true;
}
return false;
}
/**
* TArray to list
*
* @param list
* @return
*/
public static final List<CardObj> toList(ITArray list) {
List<CardObj> tem = new ArrayList<CardObj>();
for (int i = 0; i < list.size(); ++i) {
tem.add(new CardObj(list.getInt(i)));
}
return tem;
}
/**
* MAP
*
* @param cardList
* @return
*/
public static final Map<Integer, Integer> getCardNumMap(List<CardObj> cardList) {
Map<Integer, Integer> result = new HashMap<Integer, Integer>();
for (CardObj card : cardList) {
if (!result.containsKey(card.cardMod)) {
result.put(card.cardMod, 1);
} else {
int num = result.get(card.cardMod);
result.put(card.cardMod, (num + 1));
}
}
return result;
}
/**
* MAP
*
* @param cardList
* @return
*/
public static final void getCardNumMap(Map<Integer, Integer> result, List<CardObj> cardList) {
result.clear();
for (CardObj card : cardList) {
if (!result.containsKey(card.cardMod)) {
result.put(card.cardMod, 1);
} else {
int num = result.get(card.cardMod);
result.put(card.cardMod, (num + 1));
}
}
}
public static final void getCardNumMap(Map<Integer, Integer> result, List<CardObj> cardList, CardObj tempCard) {
result.clear();
result.put(tempCard.cardMod, 1);
for (CardObj card : cardList) {
if (!result.containsKey(card.cardMod)) {
result.put(card.cardMod, 1);
} else {
int num = result.get(card.cardMod);
result.put(card.cardMod, (num + 1));
}
}
}
/**
* MAP
*
* @param cardList
* @return
*/
public static final Map<Integer, List<CardObj>> getCardListMap(List<CardObj> cardList) {
Map<Integer, List<CardObj>> result = new HashMap<Integer, List<CardObj>>();
for (CardObj card : cardList) {
if (!result.containsKey(card.cardMod)) {
List<CardObj> list = new ArrayList<CardObj>();
list.add(card);
result.put(card.cardMod, list);
} else {
List<CardObj> list = result.get(card.cardMod);
list.add(card);
}
}
return result;
}
static public void removeCard(List<CardObj> cardList, List<CardObj> cards) {
for (int i = 0; i < cards.size(); i++) {
for (int j = 0; j < cardList.size(); j++) {
if (cardList.get(j).card == cards.get(i).card) {
cardList.remove(j);
break;
}
}
}
}
static public void removeCard1(List<Integer> cardList, int card, int count) {
int curCount = 0;
for (int i = 0; i < cardList.size(); i++) {
if (count == curCount) {
return;
}
if (cardList.get(i) == card) {
cardList.remove(i);
i--;
curCount++;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
package taurus.util;
public class ROBOTEventType {
/**
*
*/
public static final int ROBOT_INTOROOM_READY = 1;//等待状态
public static final int ROBOT_INTOROOM_WORKING = 2;//工作状态
public static final int ROBOT_UNUSE = 0;//未使用状态
}

View File

@ -0,0 +1,292 @@
package taurus.util;
import com.data.cache.GroupMemberCache;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.TArray;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.StringUtil;
import java.util.*;
public class Util {
public final static Random random = new Random();
static {
random.setSeed(System.currentTimeMillis());
}
/**
* list to TArray
* @param list
* @return
*/
public static final ITArray toTArray(List<Integer> list) {
ITArray result = new TArray();
for (Integer card : list) {
result.addInt(card);
}
return result;
}
/**
* call checkCard
* @param eventCard
* @param cardList
* @return
*/
@Deprecated
public static boolean cardInList(int eventCard, List<Integer> cardList) {
return checkCard(eventCard, cardList);
}
@Deprecated
public static final ITArray toMPGroup(List<int[]> list) {
ITArray result = new TArray();
for (int[] card : list) {
result.addInt(card[0]);
}
return result;
}
/**
* list to mod 100 list
* @param list
* @return
*/
public static final List<Integer> toModList(List<Integer> list){
List<Integer> tem = new ArrayList<Integer>();
for(Integer card : list) {
tem.add(card % 100);
}
return tem;
}
/**
* TArray to mod 100 list
* @param list
* @return
*/
public static final List<Integer> toModList(ITArray list){
List<Integer> tem = new ArrayList<>();
for(int i=0;i<list.size();++i) {
tem.add(list.getInt(i) % 100);
}
return tem;
}
/**
*
* @param self_seat
* @param seat
* @param people_num
* @return
*/
public static final int getPos(int self_seat, int seat, int people_num) {
int cur_seat = self_seat;
int tem = seat - (cur_seat - 1);
if (tem <= 0)
tem += people_num;
return tem - 1;
}
/**
*
* @param eventCard
* @param cardList
* @return
*/
public static final int cardNum(int eventCard, List<Integer> cardList) {
int result = 0;
for (Integer card : cardList) {
if (card == eventCard) {
result += 1;
}
}
return result;
}
/**
*
* @param eventCard
* @param cardList
* @return
*/
public static final boolean checkCard(int eventCard, List<Integer> cardList) {
for (Integer card : cardList) {
if (card == eventCard) {
return true;
}
}
return false;
}
/**
*
* @param eventCard
* @param cardList
* @param num
* @return
*/
public static final boolean checkCard(int eventCard, List<Integer> cardList, int num) {
int result = 0;
for (Integer card : cardList) {
if (card == eventCard) {
result++;
if (result == num)
return true;
}
}
return false;
}
/**
*
* @param eventCard
* @param cardList
* @param num
* @return
*/
public static final boolean checkCardAndRomve(int eventCard, List<Integer> cardList, int num) {
if (checkCard(eventCard, cardList, num)) {
removeCard(cardList, eventCard, num);
return true;
}
return false;
}
/**
* MAP
* @param cardList
* @return
*/
public static final Map<Integer, Integer> getCardNumMap(List<Integer> cardList) {
Map<Integer, Integer> result = new HashMap<Integer, Integer>();
for (Integer card : cardList) {
if (!result.containsKey(card)) {
result.put(card, 1);
} else {
int num = result.get(card);
result.put(card, (num + 1));
}
}
return result;
}
/**
*
* @param map
* @param card
* @param num
* @return
*/
public static boolean cardNum(Map<Integer, Integer> map, int card, int num) {
Integer _num = map.get(card);
if (_num != null && _num >= num) {
return true;
}
return false;
}
/**
*
* @param cardList
* @param card
* @param count
*/
public static final void removeCard(List<Integer> cardList, int card, int count) {
int curCount = 0;
for (int i = 0; i < cardList.size(); i++) {
if (cardList.get(i) == card) {
cardList.remove(i);
i--;
curCount++;
}
if (count == curCount) {
return;
}
}
}
static final public void addCard(ITArray opcard, int card, int num) {
for (int i = 0; i < num; ++i) {
opcard.addInt(card);
}
}
static final public void addCard(List<Integer> cardList, int card, int num) {
for (int i = 0; i < num; ++i) {
cardList.add(card);
}
}
/**
* 0
* @return
*/
public static int todayTimeSec() {
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
int timeSec = (int) (cal.getTimeInMillis() / 1000);
return timeSec;
}
/**
* 10
* @param timeSec
* @return
*/
public static int todayTimeSec(Long timeSec) {
Calendar cal = Calendar.getInstance();
// 指定日期
cal.setTime(new Date(timeSec));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return (int) (cal.getTimeInMillis() / 1000);
}
/**
* msg ps : param:{},param:{}
* ==> param: abc,param:abced
* @param msg
* @param params
* @return
*/
public static String stringFormat(String msg, Object... params) {
try {
if (StringUtil.isNotEmpty(msg)) {
msg = msg.replaceAll("\\{}", "\\%s");
return String.format(msg, params);
}
} catch (Exception e) {
return "";
}
return "";
}
// public static void countLog(String key,int num,Jedis jedis) {
// String day_key = key + ":d"+DateUtils.getBeginDay();
// String week_key = key + ":w"+DateUtils.getBeginWeek();
// String month_key = key + ":m"+DateUtils.getBeginMonth();
// jedis.incrBy(day_key,num);
// jedis.expire(day_key, 11*3600*24);
// jedis.incrBy(week_key,num);
// jedis.expire(week_key, 15*3600*24);
// jedis.incrBy(month_key,num);
// jedis.expire(month_key, 63*3600*24);
// }
/**
*
* @param gid
* @param uid
* @return
*/
public static long readRedisHp(int gid,int uid) {
String key = GroupMemberCache.genKey(gid, uid);
String hp = Redis.use("group1_db10").hget(key, "hp");
long cur_hp = StringUtil.isNotEmpty(hp) ? Long.parseLong(hp) : 0;
return cur_hp;
}
}

View File

@ -0,0 +1,15 @@
package robot_mj_hongzhong;
import com.taurus.permanent.TPServer;
public class Main {
public static void main(String[] args) {
System.out.println("启动红中麻将机器人服务器...");
System.out.println("服务器将监听端口8722用于游戏协议");
//启动机器人服务
TPServer.me().start();
System.out.println("红中麻将机器人服务器已启动");
}
}