table.js 109 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591
  1. 'use strict';
  2. var util = require('util');
  3. var quick = require('quick-pomelo');
  4. var P = quick.Promise;
  5. var cor = P.coroutine;
  6. var _ = require('lodash');/////是一个一致性、模块化、高性能的 JavaScript 实用工具库。
  7. //// 为什么选择 Lodash ?
  8. //// Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。
  9. //// Lodash 的模块化方法 非常适用于:
  10. //// 遍历 array、object 和 string
  11. //// 对值进行操作和检测
  12. //// 创建符合功能的函数
  13. var uuid = require('node-uuid');
  14. var Logic = require('./logic');
  15. var User = require('./user');
  16. var Score = require('./score');
  17. var conf = require('../config/games').paodekuai || {};
  18. var M = require('../../share/message');
  19. var C = require('../../share/constant');
  20. var paiJuHuiFang = require('../../share/paiJuHuiFang');//////TL++ 牌局回放
  21. var configCommon = require('../../share/configCommon');//////TL++配置相关的公共方法
  22. var setReabte = require('../../share/setReabte');//////TL++记录返利相关的公共方法
  23. var logger = quick.logger.getLogger('fhmj', __filename);
  24. // 桌子状态
  25. var STATE = { FREE: 1, PLAYING: 2, FREE2: 3 , END: 4};//ts++REFREE 二次空闲 END结束
  26. // 结算模式
  27. var MODE = { NORMAL: 1, NOCARD: 2, OFFLINE: 3 };
  28. //ts++结束模式 空闲0,游戏中1, 正常结束3,房主解散3,断线解散4,断线解散5,系统解散6
  29. var ENDMODE = { FREE: 0,PLAYING: 1, OWNEREND: 2,NORMALEND: 3,REGEND: 4, OFFLINEEND: 5, SYSTEMEND: 6 };
  30. // 金币消耗
  31. const COSTS = conf.sit_costs || {};
  32. /////TL++,下面这几行为了记录用户行为
  33. // var log4js2 = require("log4js");////cssj
  34. // var log4js_config2 = require("./logConf.json");
  35. // log4js2.configure(log4js_config2);
  36. // var LogFile2 = log4js2.getLogger('log_file');////cssj
  37. var checkVersion = function () {
  38. // let confCodeVer = require('../config/VersionConfig').codeVer || {};
  39. // // console.warn("pdk的table中检查logic版本111 "+JSON.stringify(confCodeVer));
  40. // if(confCodeVer.pdkLogic){
  41. // delete require.cache[require.resolve('../config/VersionConfig')];
  42. // let confCodeVer2 = require('../config/VersionConfig').codeVer || {};
  43. // // console.warn("pdk的table中检查logic版本222 "+confCodeVer.pdkLogic +" "+ confCodeVer2.pdkLogic);
  44. // if(confCodeVer.pdkLogic && confCodeVer2.pdkLogic && confCodeVer.pdkLogic != confCodeVer2.pdkLogic){
  45. // delete require.cache[require.resolve('./logic')];
  46. // Logic = require('./logic');
  47. // // console.warn("pdk的table中的logic更新了 ")
  48. // }
  49. // }
  50. }
  51. // 构造方法
  52. var Table = function (cPlayerId,cUserId,cName,cHead,game, id, cell, round, type,gameKindTL,playerAllCount,upId,other,agentId,yxndlbTime,yxndlbTip) {
  53. let str3 = "table构造方法.......id: "+id + " type " + type+" game "+game.id;
  54. logger.warn(str3);////cssj
  55. checkVersion();
  56. this.app = game.app;
  57. this.gameId = 10008;
  58. this.game = game;
  59. this.id = id;
  60. this.recordid = uuid.v1()+'_'+id;//ts++唯一记录
  61. this.upId = upId;//ts++上局的ID
  62. this.type = type;
  63. this.agentId=agentId;
  64. this.yxndlbTime = yxndlbTime;
  65. this.yxndlbTip = yxndlbTip;
  66. var num_cost = 50;
  67. num_cost =parseInt(COSTS[round]);
  68. this.other = other;//////TL++2人3人的游戏规则
  69. // console.warn("222创建房间的other",other,this.other," gameKindTL ",gameKindTL," type " ,type);
  70. this.isHTSFB = false;//是否红桃十翻倍
  71. if(this.other & 1){
  72. this.isHTSFB = true;
  73. }
  74. this.isZDBKC = false;//是否炸弹不可拆
  75. if(this.other & 2){
  76. this.isZDBKC = true;
  77. }
  78. this.isSiDaiEr = false;//是否可四带2
  79. if(this.other & 4){
  80. this.isSiDaiEr = true;
  81. }
  82. this.isSiDaiSan = false;//是否可四带3
  83. if(this.other & 32){
  84. this.isSiDaiSan = true;
  85. }
  86. this.cardCount = 15;//张数
  87. if(this.other & 8){//
  88. this.cardCount = 15;
  89. }
  90. else if(this.other & 16){//
  91. this.cardCount = 16;
  92. }
  93. this.isXSSYP = false;//是否显示剩余牌
  94. if(this.other & 64){
  95. this.isXSSYP = true;
  96. }
  97. this.isHaveJPQ = false;//是否有记牌器
  98. if(this.other & 128){
  99. this.isHaveJPQ = true;
  100. }
  101. // this.isYPBC = true;//是否有牌必出(能大过必须出牌大掉)
  102. // console.warn("是否红桃十翻倍 "+this.isHTSFB)
  103. // console.warn("是否炸弹不可拆 "+this.isZDBKC)
  104. // console.warn("是否可四带2 "+this.isSiDaiEr)
  105. // console.warn("是否可四带3 "+this.isSiDaiSan)
  106. // console.warn("张数 "+this.cardCount)
  107. // console.warn("是否显示剩余牌 "+this.isXSSYP)
  108. // this.isYPBC = true;//是否有牌必出(能大过必须出牌大掉)
  109. this.isYBQZDCP = true;//是否要不起自动出牌
  110. this.cost = num_cost;
  111. this.over = 0;
  112. this.round = round;
  113. this.stime = 0;
  114. this.ctime = Date.now();
  115. this.etime = 0;
  116. this.lconfigCommon = null;
  117. // 人数
  118. this.ccount = playerAllCount;//Logic.CHAIR_COUNT;
  119. this.mcount = Logic.CARDS_COUNT;
  120. // 房主
  121. this.ownerChairId = -1;//房主的chairid
  122. this.ownerId = cPlayerId;//房主Id
  123. this.ownerUid = cUserId;//房主的userID
  124. this.ownerName = cName;
  125. this.ownerHeadUrl = cHead;
  126. // 数据
  127. var logic = new Logic(type,gameKindTL,playerAllCount,other);
  128. this.logic = logic;
  129. this.score = new Score(this);
  130. this.handCards = Array(this.ccount);
  131. this.users = Array(this.ccount);
  132. this.chBanker = 0;
  133. this.bankFlag = 0;
  134. this.isHTSSC = false;//是否是黑桃三首出
  135. this.tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  136. this.lastOut = {chair:-1,type:-1,cards:[]};//上次有效的出牌(要不起出的[]不算有效出牌)
  137. this.blZDInfo = [[]];//本轮炸弹信息[[chair,card]]
  138. this.bloutCard = logic.fillDeep(Array(this.ccount),null);;////目前本轮每个玩家的出牌[]表示该玩家过牌,null表示本轮该玩家还未出牌
  139. this.outCards = logic.fillDeep(Array(this.ccount), []);
  140. // 标记
  141. this.outCard = [];//[]表示要不起
  142. this.outerId = -1;
  143. this.currentId = -1;
  144. this.zhaniaoChair = -1;//扎鸟(勾选了红桃十翻倍且拿到红桃十的玩家)玩家id
  145. this.nextCardCount = this.cardCount;//当前玩家的下家手牌个数,为了判断下家只剩一张牌时出单牌时必须出手牌里最大那张
  146. this.ksNewLunTimer = null;//开始新一轮定时器
  147. this.autoOutLastTimer = null;//自动出掉最后一手牌定时器
  148. this.autoOutTimer = null;//托管自动出牌定时器
  149. this.autoReadyTimer = null;//托管中自动准备定时器
  150. this.autoReadyTimer2 = null;//未托管自动准备定时器
  151. this.everyIsAutoOut = _.fill(Array(this.ccount), 0);
  152. // 胡牌者
  153. this.winner = { lead: -1, chs: [] };
  154. // 底分
  155. this.cell = cell;
  156. // 围观者
  157. this.lookers = [];
  158. //结束时的继线用户
  159. this.leaveUsers = [];
  160. this.leaveUsersBS = [];//比赛中自动准备的断线用户,在自动准备时添加在回到桌子时删除,用于最后一局结束之后让断线玩家退出房间
  161. //leaveUsersBS是上面leaveUsers这个字段在比赛情况下的补充,因为leaveUsers没有收录在比赛时非最后一局过程中断线的玩家
  162. // 状态
  163. this.state = STATE.FREE;
  164. // 申请结束标记
  165. this.overFlag = 0;
  166. this.overTimer = null;
  167. this.endTableTime = 60;//////TL++,申请解散房间之后60秒之后不操作则认为同意解散
  168. this.reqJieSan = [-1,-1,-1,-1];/////解散桌子数据,前面为chirid后面为情况-1:未操作 0:拒绝 1:同意 2为解散发起
  169. //断线 结束定时器
  170. this.endTimer = null;
  171. //////以下全为TL++
  172. /////TL++,补花定时器,防止连续补花太快
  173. this.PJHF = new paiJuHuiFang();
  174. this.backStartTimer = null;//////重入之后系统会自动准备为了解决可能没牌的问题2秒之后才开始游戏
  175. this.PaijuHuiFang = [];////TL++,牌局回放
  176. this.isYJJSGL = false;/////是否已经执行过结算函数了
  177. this.isYJKSGL = false;/////是否已经执行过开始函数了
  178. this.JSFJTimeout = null;//解散房间倒计时
  179. this.JSFJTime = 60;//解散房间倒计时60秒
  180. this.SQJSTime = null;//申请解散房间的时间,用于计算解散房间倒计时所剩的时间
  181. this.gameNeverStart = true;//游戏是否从未开始过,用于解散房间判断
  182. this.pjhffileName = [];//用于记录玩家牌局回放的json文件名
  183. this.playerPosList = [[],[],[],[]];//记录玩家的位置信息数组
  184. this.gameKindTL = gameKindTL || 1;//平搓还是冲刺 = 1代表平搓 = 2代表冲刺
  185. this.playerAllCount = playerAllCount || 4;//游戏人数 = 2表示2人局 = 3表示3人局 = 4表示4人局
  186. this.isNeverStart = true;//游戏是否从未开始
  187. this.sszjDataList = [];//设置实时战绩的数据
  188. this.isEveryZZ = false;//是否每一个人都做过庄
  189. this.chairArry = [0,1,2];//
  190. this.sszjs = [];//ts++实时战绩
  191. this.LWKF = [10,10,10,10,10];//////TL++礼物扣费
  192. this.isGameOk=false;//ts++牌局正常结束
  193. this.agentRebate=0;//ts++本局的返利
  194. this.yjxrzj = false;
  195. // delete require.cache[require.resolve('../../share/setReabte')];
  196. // setReabte = require('../../share/setReabte');
  197. this.lsetReabte = new setReabte(this.app);
  198. if(this.lsetReabte.getIsBS(this.agentId,this.ownerName,this.ownerUid)) this.cost = 0;//比赛免费
  199. };
  200. // 导出状态
  201. Table.STATE = STATE;
  202. //ts++ 结束模式
  203. Table.ENDMODE = ENDMODE;
  204. // 导出类
  205. module.exports = Table;
  206. // 原型对象
  207. var proto = Table.prototype;
  208. // 是否站满
  209. proto.isFull = function () {
  210. return (this.lookers.length >= 5);
  211. };
  212. // 是否准备
  213. proto.isReady = function () {
  214. for (let user of this.users) {
  215. if (!user || !user.isReady()) return false;
  216. }
  217. return true;
  218. };
  219. // ts++是否二次准备
  220. proto.isReady2 = function () {
  221. for (let user of this.users) {
  222. if (!user || !user.isReady2()) return false;
  223. }
  224. return true;
  225. };
  226. // 是否游戏中
  227. proto.isPlaying = function () {
  228. return this.state > STATE.FREE;
  229. };
  230. // 是否全在线
  231. proto.isOnline = function () {
  232. for (let user of this.users) {
  233. if (user && user.isOffline()) return false;
  234. }
  235. return true;
  236. };
  237. // 是否全断线
  238. proto.isOffline = function () {
  239. for (let user of this.users) {
  240. if (!user || !user.isOffline()) return false;
  241. }
  242. return true;
  243. };
  244. // 是否空桌
  245. proto.isEmpty = function () {
  246. if (this.lookers.length > 0) return false;
  247. for (let i = 0; i < this.users.length; ++i) {
  248. if (this.users[i]) return false;
  249. }
  250. return true;
  251. };
  252. // 局数完成
  253. proto.isGameOver = function () {
  254. let str3 = "table 局数完成 .......id: "+ this.id + " this.over " + this.over;
  255. logger.warn(str3);////cssj
  256. return (this.over >= this.round);
  257. };
  258. // 重置本局
  259. proto.resetRound = function () {
  260. _.fill(this.handCards, null);
  261. this.zhaniaoChair = -1;//扎鸟(勾选了红桃十翻倍且拿到红桃十的玩家)玩家id
  262. this.nextCardCount = this.cardCount;//当前玩家的下家手牌个数,为了判断下家只剩一张牌时出单牌时必须出手牌里最大那张
  263. if(this.ksNewLunTimer)
  264. {
  265. clearTimeout(this.ksNewLunTimer);
  266. this.ksNewLunTimer = null;
  267. }
  268. if(this.autoOutLastTimer)
  269. {
  270. clearTimeout(this.autoOutLastTimer);
  271. this.autoOutLastTimer = null;
  272. }
  273. if(this.autoOutTimer)
  274. {
  275. clearTimeout(this.autoOutTimer);
  276. this.autoOutTimer = null;
  277. }
  278. if(!this.lsetReabte.getIsBS(this.agentId,this.ownerName,this.ownerUid)) this.everyIsAutoOut = _.fill(Array(this.ccount), 0);
  279. this.winner.chs = [];
  280. this.winner.lead = -1;
  281. this.logic.fillDeep(this.outCards, []);
  282. this.isHTSSC = false;//是否是黑桃三首出
  283. this.tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  284. this.lastOut = {chair:-1,type:-1,cards:[]};//上次有效的出牌(要不起出的[]不算有效出牌)
  285. this.blZDInfo = [[]];//本轮炸弹信息[[chair,card]]
  286. this.bloutCard = this.logic.fillDeep(Array(this.ccount),null);;////目前本轮每个玩家的出牌[]表示该玩家过牌,null表示本轮该玩家还未出牌
  287. this.outCard = [];
  288. this.outerId = -1;
  289. this.currentId = -1;
  290. };
  291. // 发送消息
  292. proto.pushMsgAsync = cor(function* (cidOrIds, route, msg) {
  293. // console.warn("444WWWWWWWTTTTTT",cidOrIds, route, msg);
  294. var playerIds = [];
  295. if (Array.isArray(cidOrIds)) playerIds = cidOrIds;
  296. else {
  297. if (cidOrIds < 0 || cidOrIds >= this.users.length) {
  298. for (let user of this.users) {
  299. if (user) playerIds.push(user.id);
  300. }
  301. for (let lker of this.lookers) {
  302. playerIds.push(lker.id);
  303. }
  304. } else {
  305. let user = this.users[cidOrIds];
  306. if (user) playerIds.push(user.id);
  307. // console.warn("555WWWWWWWTTTTTT",cidOrIds, route, user.name);
  308. }
  309. }
  310. if (playerIds.length > 0) {
  311. let channelId = 'xct:' + this.id;
  312. // console.warn("666WWWWWWWTTTTTT",cidOrIds, route, playerIds,msg);
  313. return this.app.controllers.push._pushAsync(channelId, playerIds, route, msg);
  314. }
  315. });
  316. // 围观消息
  317. proto.lookMsgAsync = cor(function* (route, msg) {
  318. var playerIds = [];
  319. for (let lker of this.lookers) {
  320. playerIds.push(lker.id);
  321. }
  322. if (playerIds.length > 0) {
  323. let channelId = 'xct:' + this.id;
  324. return this.app.controllers.push._pushAsync(channelId, playerIds, route, msg);
  325. }
  326. });
  327. // 获得桌子信息
  328. proto.getTableInfo = function () {
  329. // 桌子信息
  330. let endTableTime = Math.floor((this.SQJSTime - Date.now())/1000);
  331. var tableInfo = {
  332. id: this.id,
  333. gameId: this.gameId,
  334. type: this.type,
  335. cost: this.cost,
  336. over: this.over,
  337. round: this.round,
  338. users: [],
  339. lookers: [],
  340. agentId: this.agentId,
  341. ownerId: -1,//this.ownerChairid
  342. ownerUserId: this.ownerUid,////TL++,房主的userID
  343. ownerName: this.ownerName,//////TL++,房主的昵称
  344. ownerHeadUrl: this.ownerHeadUrl,//////TL++,房主的头像地址
  345. gameKindTL: this.gameKindTL,////平搓还是冲刺 = 1代表平搓 = 2代表冲刺
  346. playerAllCount: this.playerAllCount,////游戏人数 = 2表示2人局 = 3表示3人局 = 4表示4人局
  347. other: this.other,
  348. creatTime : this.ctime,
  349. nowTime : Date.now(),
  350. state: this.state,
  351. sszjDataList: this.sszjDataList,////TL++,设置实时战绩的数据
  352. // isZHYZ: this.logic.isZHYZ, /////TL++,是否最后一张
  353. playerPosList: this.playerPosList,/////TL++玩家位置数据
  354. chairArry: this.chairArry,/////TL++
  355. isNeverStart: this.isNeverStart,/////TL++,游戏是否从未开始
  356. overFlag:this.overFlag,//ts++房间解散标识
  357. endTableTime:endTableTime,
  358. recordid:this.recordid,
  359. bloutCard: this.bloutCard,////目前本轮每个玩家的出牌[]表示该玩家过牌,null表示本轮该玩家还未出牌
  360. currentId: this.currentId,
  361. yxndlbTime:this.yxndlbTime,
  362. yxndlbTip:this.yxndlbTip,
  363. reqJieSan:this.reqJieSan
  364. };
  365. // 正在游戏
  366. var isPlaying = this.isPlaying();
  367. if (isPlaying) {
  368. tableInfo.banker = this.chBanker;
  369. tableInfo.stime = Date.now() - this.stime;
  370. tableInfo.lastCount = this.logic.leaveCount();
  371. tableInfo.nextCardCount = this.nextCardCount;
  372. //////TL++ end,游戏过程中重入
  373. }
  374. // 桌上玩家
  375. for (let i = 0; i < this.users.length; ++i) {
  376. let user = this.users[i];
  377. if (user) {
  378. let score = this.score.getScore(user.id);
  379. let uinfo = {
  380. account: user.account, name: user.name, sex: user.sex, headurl: user.headurl,
  381. state: user.state2, score: score, chairId: user.chairId
  382. };
  383. if (isPlaying) {
  384. uinfo.outCards = this.outCards[i];
  385. let handCard = this.handCards[i] || [];
  386. uinfo.handCount = handCard.length;
  387. }
  388. tableInfo.users.push(uinfo);
  389. }
  390. }
  391. // 围观玩家
  392. for (let i = 0; i < this.lookers.length; ++i) {
  393. let user = this.lookers[i];
  394. if (user) {
  395. tableInfo.lookers.push({ account: user.account, name: user.name, sex: user.sex, headurl: user.headurl });
  396. }
  397. }
  398. return tableInfo;
  399. };
  400. // 回到桌子
  401. proto.backAsync = cor(function* (user) {
  402. let str3 = "table回到桌子.......id: "+ this.id + " user.chairId: " + user.chairId + " user.name: " + user.name ;
  403. logger.warn(str3);////cssj
  404. user.offlinetime=0;//ts++
  405. var data = { chairId: String(user.chairId) };
  406. var chairId = user.chairId;
  407. if (chairId != -1) {
  408. // 加入频道
  409. var connectorId = user.connectorId || '';
  410. if (connectorId) {
  411. let channelId = 'xct:' + this.id;
  412. yield this.app.controllers.push._joinAsync(channelId, user.id, connectorId);
  413. }
  414. // 恢复状态
  415. if (this.state == STATE.FREE) {
  416. yield this.readyGameAsync(user);
  417. } else if (this.state == STATE.PLAYING) {
  418. //user.state = User.STATE.PLAYING;//ts--
  419. user.state2 = User.STATE.PLAYING;//ts++
  420. // data.mask = String(this.masks[chairId]);
  421. data.handCards = this.handCards[chairId];
  422. // 状态通知
  423. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.STATE_CHANGE, data: { chairId: String(user.chairId), state: String(user.state2), state2: String(user.state2) } });
  424. }else if (this.state == STATE.FREE2) {//ts++二次准备
  425. //user.state = User.STATE.PLAYING;//ts--
  426. user.state2 = User.STATE.READY;
  427. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.STATE_CHANGE, data: { chairId: String(user.chairId), state: String(user.state2), state2: String(user.state2) } });
  428. if (this.isReady2() && !this.isGameOk)
  429. {
  430. if(!this.backStartTimer){
  431. if(this.autoReadyTimer2)
  432. {
  433. clearTimeout(this.autoReadyTimer2);
  434. this.autoReadyTimer2 = null;
  435. }
  436. this.backStartTimer = this.app.timer.setTimeout(() => this.backStartTimeAsync(), 2 * 1000);//延迟2秒开始游戏
  437. }
  438. }
  439. }
  440. // 取消计时
  441. if (this.isOnline() && this.endTimer) {
  442. clearTimeout(this.endTimer);
  443. this.endTimer = null;
  444. }
  445. }
  446. // 数据处理
  447. data.fee = this.score.isFeed(user.id) ? '0' : '1';
  448. data.table = this.getTableInfo();
  449. let isAutoOut = 0;
  450. if (chairId != -1) {
  451. isAutoOut = this.everyIsAutoOut[chairId];
  452. data.table.dczsList = this.logic.getDCZSList(chairId);
  453. data.table.jpqsysj = this.logic.everyJPQSYSJ[chairId];
  454. }
  455. data.table.isAutoOut = isAutoOut;
  456. let tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  457. if(this.currentId > -1 && chairId == this.currentId) tipInfo = this.tipInfo;
  458. data.table.tipInfo = this.logic.deepCloneTL(tipInfo);
  459. // console.warn("this.leaveUsersBS 用户回到桌子 "+user.id + " " +JSON.stringify(this.leaveUsersBS));
  460. let bsdxxb = this.leaveUsersBS.indexOf(user.id);
  461. if(bsdxxb != -1) {
  462. this.leaveUsersBS.splice(bsdxxb, 1);//只要玩家能回到桌子之前的字段leaveUsers就能节奏处理这个用户了
  463. // console.warn("this.leaveUsersBS 删除元素 "+user.id + " " +JSON.stringify(this.leaveUsersBS));
  464. }
  465. return { code: C.OK, data: data };
  466. });
  467. //ts++重入后自动开始
  468. proto.backStartTimeAsync = cor(function* () {
  469. yield this.startGameAsync();
  470. });
  471. // 加入桌子
  472. proto.joinAsync = cor(function* (user) {
  473. // 撤出删除队列
  474. //this.game.cancelDelete(this.id);
  475. // 加入桌子之前
  476. yield this.beforeJoinAsync(user);
  477. // 加入围观者
  478. this.lookers.push(user);
  479. // 加入桌子之后
  480. yield this.afterJoinAsync(user);
  481. // 数据返回处理
  482. var data = { chairId: String(user.chairId) };
  483. data.fee = this.score.isFeed(user.id) ? '0' : '1';
  484. data.table = this.getTableInfo();
  485. return { code: C.OK, data: data };
  486. });
  487. // 加入桌子之前
  488. proto.beforeJoinAsync = cor(function* (user) {
  489. var connectorId = user.connectorId || '';
  490. if (connectorId) {
  491. let channelId = 'xct:' + this.id;
  492. return this.app.controllers.push._joinAsync(channelId, user.id, connectorId);
  493. }
  494. });
  495. // 加入桌子之后
  496. proto.afterJoinAsync = cor(function* (user) {
  497. // 加入通知
  498. return this.pushMsgAsync(-1, 'paodekuai_event', {
  499. type: M.JOIN, data: { account: user.account, userId: user.userId, name: user.name, sex: user.sex, headurl: user.headurl,playerPosList: this.playerPosList }
  500. });
  501. });
  502. // 坐下桌子
  503. proto.seatAsync = cor(function* (user, chairId) {
  504. // let chairId = this.chairArry[_chairId];
  505. // console.warn("坐下桌子不不vvvvvv",chairId,_chairId,this.chairArry,this.users.length);
  506. // 参数校验
  507. if (chairId < 0 || chairId >= this.ccount) {
  508. return { code: C.FAILD, msg: C.CHAIR_NOT_FOUND };
  509. }
  510. if (this.users[chairId]) {
  511. // console.warn("坐下桌子死了vv000",this.users[chairId]);
  512. // console.warn("坐下桌子死了vvvvvv",this.users.length,this.users);
  513. return { code: C.FAILD, msg: C.CHAIR_HAS_SOMEONE };
  514. }
  515. // 查找玩家
  516. var player = yield this.app.models.Player.findByIdAsync(user.id, 'diamond cost');
  517. if (!player) {
  518. return { code: C.FAILD, msg: C.PLAYER_NOT_FOUND };
  519. }
  520. if (this.users[chairId]) {
  521. return { code: C.FAILD, msg: C.CHAIR_HAS_SOMEONE };
  522. }
  523. // 调换座位
  524. if (user.chairId != -1) {
  525. return this.changeChairAsync(user, chairId);
  526. }
  527. // 围观玩家
  528. var pos = _.findIndex(this.lookers, (u) => (u.id == user.id));
  529. if (pos == -1) {
  530. return { code: C.FAILD, msg: C.TABLE_NOT_USER };
  531. }
  532. //ts++
  533. let dSource=player.diamond;
  534. let dNow=player.diamond;
  535. //坐下花费
  536. var costdata = null;
  537. if (!this.score.isFeed(user.id)) {
  538. if (player.diamond < this.cost) {
  539. return { code: C.FAILD, msg: C.GAME_DIAMOND_LOW };
  540. }//////TL++zsyl 1000局测完之后要放出来的
  541. player.diamond -= this.cost;
  542. player.cost = (player.cost || 0) + this.cost;
  543. dNow-=this.cost;
  544. this.score.addUser(user.id,chairId,user.userId, user.name, user.sex, user.headurl,user.diamond,this.gameKindTL);
  545. costdata = { cost: String(this.cost) };
  546. }
  547. // 坐下处理
  548. this.lookers.splice(pos, 1);
  549. this.users[chairId] = user;
  550. user.chairId = chairId;
  551. user.state = User.STATE.READY;
  552. yield this.afterSeatAsync(user);
  553. if (player.isModified())
  554. {
  555. yield player.saveAsync();/////只有第一次坐下的时候才会执行
  556. // 钻石记录
  557. var diamondrecord = new this.app.models.DiamondRecord({
  558. _id: uuid.v1(),
  559. playerId: user.id,
  560. dType: 3,//坐下
  561. dSource: dSource,
  562. dSwap: -1*this.cost,
  563. dNow: dNow,
  564. tableId: this.recordid
  565. });
  566. yield diamondrecord.saveAsync();
  567. // console.warn("ts++坐下-------------------钻石记录");
  568. if (costdata) yield this.pushMsgAsync(chairId, 'paodekuai_event', { type: M.COST_FEE, data: costdata });
  569. }
  570. if (this.isHaveJPQ && this.state == STATE.FREE){
  571. let jpqsysj = 0;//记牌器剩余时间
  572. let jipaiqi = yield this.app.models.JiPaiQi.findByIdAsync(user.id, 'jpqdqsj');
  573. if (jipaiqi) {
  574. let currTime = Date.now();
  575. if(jipaiqi.jpqdqsj > 0 && jipaiqi.jpqdqsj >= currTime) jpqsysj = jipaiqi.jpqdqsj - currTime;
  576. }
  577. let index = -1;
  578. for (var i = 0; i < this.logic.uidsfydsq.length; i++) {
  579. if(user.userId == this.logic.uidsfydsq[i][0]){
  580. index = i;
  581. break;
  582. }
  583. }
  584. if(index == -1) this.logic.uidsfydsq.push([user.userId,jpqsysj]);
  585. else this.logic.uidsfydsq[index][1] = jpqsysj;
  586. }
  587. // if (this.isReady()) yield this.pushMsgAsync(this.ownerChairid, 'paodekuai_event', { type: M.START_BUTTON });//////TL++zsyl所有人准备之后通知房主点击开始游戏
  588. if (this.state == STATE.FREE && this.isReady() && !this.isGameOk) {
  589. yield this.randomChangeChairTL();
  590. }
  591. return { code: C.OK, chairId: String(chairId) };
  592. });
  593. // 调换座位 自己坐下之后点击另外一个位子的时候调用这个方法 这个参数user输出之后相当的长
  594. proto.changeChairAsync = cor(function* (user, chairId) {
  595. if (this.state != STATE.FREE) {
  596. return { code: C.FAILD, msg: C.TABLE_NOT_FREE };
  597. }
  598. if (this.users[chairId]) {
  599. return { code: C.FAILD, msg: C.CHAIR_HAS_SOMEONE };
  600. }
  601. // var _chairId = user.chairId;
  602. // delete this.users[_chairId];
  603. // this.users[chairId] = user;
  604. // user.chairId = chairId;
  605. // user.state = User.STATE.READY;
  606. // yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.CHAIR_CHANGE, data: { oldId: String(_chairId), newId: String(chairId), state: String(user.state), state2: String(user.state2) } });
  607. // // if (this.ownerChairid == _chairId) {
  608. // // this.ownerChairid = chairId;
  609. // // // 换房主通知
  610. // // yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.OWNER_CHANGE, data: { ownerChairid: String(this.ownerChairid) } });
  611. // // }
  612. return { code: C.OK, chairId: String(chairId) };
  613. });
  614. // 坐下桌子之后
  615. proto.afterSeatAsync = cor(function* (user) {
  616. let posListTL = {
  617. chairId: user.chairId,
  618. headurl: user.headurl,
  619. longitude: user.longitude, // 经度,浮点数,范围为180 ~ -180。
  620. latitude: user.latitude, // 纬度,浮点数,范围为90 ~ -90
  621. }
  622. this.playerPosList[user.chairId] = posListTL/////TL++记录玩家的位置信息数组
  623. // 坐下通知
  624. let score = this.score.getScore(user.id);
  625. yield this.pushMsgAsync(-1, 'paodekuai_event', {///////发送坐下
  626. type: M.SEAT, data: {
  627. account: user.account,
  628. name: user.name,
  629. sex: user.sex,
  630. headurl: user.headurl,
  631. state: String(user.state),
  632. score: String(score),
  633. chairId: String(user.chairId),
  634. userId: String(user.userId),
  635. playerPosList: this.playerPosList, /////TL++记录玩家的位置信息数组
  636. }
  637. });
  638. });
  639. //////TL++,在首次游戏开始的时候随机打乱用户的座位
  640. proto.randomChangeChairTL = cor(function* () {
  641. // console.warn("111在首次游戏开始的时候随机打乱用户的座位",this.users[0].name,this.users[1].name,this.users[2].name,this.users[3].name);
  642. // console.warn("1在首次游戏开始的时候随机打乱用户的座位",this.users[0].chairId,this.users[1].chairId,this.users[2].chairId,this.users[3].chairId);
  643. if(this.playerAllCount > 2){
  644. let changeResult = [];
  645. if (this.over <= 0) {///////本房间开始的第一局游戏
  646. for (let i = 0; i < 1; i++) {
  647. let oldchaieID = i;
  648. let olduser = this.users[i];
  649. let newchaieID = Math.floor(Math.random()*this.playerAllCount);////// 区间[0,3]取整数
  650. while (newchaieID == oldchaieID) {
  651. newchaieID = Math.floor(Math.random()*this.playerAllCount);////// 区间[0,3]取整数
  652. }
  653. let newuser = this.users[newchaieID];
  654. // console.warn("222在首次游戏开始的时候随机打乱用户的座位",oldchaieID,newchaieID);
  655. // console.warn("xxxxxxxxx删除有没有用啊",this.users.length);
  656. delete this.users[newchaieID];
  657. delete this.users[oldchaieID];
  658. // console.warn("xxxxxxxxx22删除有没有用啊",this.users.length);
  659. this.users[newchaieID] = olduser;
  660. this.users[newchaieID].chairId = newchaieID;
  661. // this.users[newchaieID].id = newuser.id;
  662. this.users[oldchaieID] = newuser;
  663. this.users[oldchaieID].chairId = oldchaieID;
  664. // this.users[oldchaieID].id = olduser.id;
  665. changeResult.push([oldchaieID,newchaieID])
  666. }
  667. // console.warn("333在首次游戏开始的时候随机打乱用户的座位",this.users[0].name,this.users[1].name,this.users[2].name,this.users[3].name);
  668. // console.warn("3在首次游戏开始的时候随机打乱用户的座位",this.users[0].chairId,this.users[1].chairId,this.users[2].chairId,this.users[3].chairId);
  669. // console.warn("3在首次游戏开始的时候随机打乱用户的座位",this.users[0].id,this.users[1].id,this.users[2].id,this.users[3].id);
  670. // console.warn("3在首次游戏开始的",this.users[0]);
  671. ////// this.users 发送给前端会代码报错
  672. // yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.CHAIR_DALUAN, data: { changeResult:changeResult } });
  673. /////TL++
  674. for (let i = 0; i < this.users.length; ++i) {
  675. this.score.setUserChair(this.users[i].id,this.users[i].chairId)
  676. }
  677. let daluanData = [];
  678. var isPlaying = this.isPlaying();
  679. for (let i = 0; i < this.users.length; ++i) {
  680. let user = this.users[i];
  681. if (user) {
  682. let score = this.score.getScore(user.id);
  683. let uinfo = {
  684. account: user.account, name: user.name, sex: user.sex, headurl: user.headurl,
  685. state: user.state, score: score, chairId: user.chairId
  686. };
  687. if (isPlaying) {
  688. uinfo.outCards = this.outCards[i];
  689. let handCard = this.handCards[i] || [];
  690. uinfo.handCount = handCard.length;
  691. }
  692. daluanData.push(uinfo);
  693. }
  694. }
  695. // this.score.delUser(user.id);
  696. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.CHAIR_DALUAN, data: { daluanData:daluanData } });
  697. }
  698. }
  699. for (let i = 0; i < this.users.length; ++i) {
  700. let user = this.users[i];
  701. if (user) {
  702. for (var j = 0; j < this.logic.uidsfydsq.length; j++) {
  703. if(user.userId == this.logic.uidsfydsq[j][0]){
  704. this.logic.everyJPQSYSJ[i] = this.logic.uidsfydsq[j][1];
  705. break
  706. }
  707. }
  708. }
  709. }
  710. // console.warn("444在首次游戏开始的时候随机打乱用户的座位",changeResult);
  711. // this.starTimer = this.app.timer.setTimeout(() => this.startGameAsync(), 500);
  712. yield this.startGameAsync()/////TL++,在首次游戏的时候随机打乱用户的座位
  713. });
  714. // 站起桌子
  715. proto.standAsync = cor(function* (user) {
  716. let str3 = "table 站起桌子.......id: "+ this.id + " user.chairId: " + user.chairId + " user.name: " + user.name ;
  717. logger.warn(str3);////cssj
  718. var chairId = user.chairId;
  719. if (chairId != -1) {
  720. user.state = User.STATE.FREE;
  721. delete this.users[chairId];
  722. delete this.handCards[chairId];
  723. user.chairId = -1;
  724. this.lookers.push(user);
  725. yield this.afterStandAsync(user, chairId);
  726. }
  727. return { code: C.OK };
  728. });
  729. // 站起桌子之后
  730. proto.afterStandAsync = cor(function* (user, chairId) {
  731. // 站起通知
  732. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.STAND, data: { chairId: String(chairId) } });
  733. //if (this.ownerChairid == -1) this.ownerChairid = -1;//////TL++,房主坐下之后重置房主chairid
  734. /////TL++,作坐下的玩家离开桌子之后将他的位置信息从位置列表里面删除
  735. if(chairId != -1) this.playerPosList[chairId] = [];
  736. // 桌主离开
  737. //////TL++zsyl,原先的这个逻辑是房主站起之后会切换房主
  738. // if (chairId == this.ownerChairid) {
  739. // let newCid = _.findIndex(this.users, (user) => user);
  740. // this.ownerChairid = newCid;
  741. // if (newCid != -1) this.ownerUid = this.users[newCid].id;
  742. // // 换房主通知
  743. // yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.OWNER_CHANGE, data: { ownerChairid: String(this.ownerChairid) } });
  744. // }
  745. //是否退费
  746. // console.warn("ts++++++++站起桌子之后");
  747. var scorer = this.score.getUser(user.id);
  748. if (scorer && scorer.over <= 0) {
  749. // console.warn("ts++没有开始游戏退分",user.id);
  750. this.score.delUser(user.id);
  751. let player = yield this.app.models.Player.findByIdAsync(user.id, 'diamond cost');
  752. if (player) {
  753. // console.warn("ts++没有开始游戏退分",player.diamond);
  754. let dSource=player.diamond;
  755. let dNow=player.diamond+this.cost;
  756. player.diamond += this.cost;
  757. player.cost -= this.cost;
  758. yield player.saveAsync();
  759. //return this.app.controllers.player.pushAsync(user.id, 'paodekuai_event', { type: M.BACK_FEE, data: { back: String(this.cost) } });
  760. // 退费 钻石记录
  761. var diamondrecord = new this.app.models.DiamondRecord({
  762. _id: uuid.v1(),
  763. playerId: user.id,
  764. dType: 4,//退费
  765. dSource: dSource,
  766. dSwap: this.cost,
  767. dNow: dNow,
  768. tableId: this.recordid
  769. });
  770. yield diamondrecord.saveAsync();
  771. // console.warn("ts++退分-------------------钻石记录");
  772. //var costdata = { cost: String(-1*this.cost) };
  773. //if (costdata) yield this.pushMsgAsync(chairId, 'paodekuai_event', { type: M.COST_FEE, data: costdata });
  774. }
  775. }
  776. else
  777. {
  778. // console.warn(" user.cost "+user.cost);
  779. if(user.cost==0 && user.spreadId)//ts++推荐人奖励
  780. {
  781. // let spreader = yield this.app.models.Player.findByIdAsync(user.spreadId, 'spreadCount spreadRebate');
  782. // if (spreader) {
  783. // spreader.spreadCount += 1;
  784. // spreader.spreadRebate += 100;
  785. // yield spreader.saveAsync();
  786. // }
  787. ////20200928因为现在的spreadId存的是userId,所以上面那段用不了了
  788. // console.warn("邀请新人送钻石活动 this.etime "+this.etime);
  789. if(!this.lconfigCommon) {
  790. // console.warn("邀请新人送钻石活动 this.lconfigCommon 不存在 "+this.etime);
  791. this.lconfigCommon = new configCommon(this.app);
  792. }
  793. let yxhdxx = this.lconfigCommon.getActiveOpenTime(1);//邀请新人送钻石活动是否开启和开始结束时间的信息
  794. let isKQ = false;//邀请新人送钻石活动是否开启
  795. if(yxhdxx && yxhdxx.open && yxhdxx.startTime && yxhdxx.endTime) isKQ = true;
  796. // console.warn("获取配置信息 yxhdxx "+JSON.stringify(yxhdxx));
  797. if(isKQ && this.etime >= yxhdxx.startTime && this.etime < yxhdxx.endTime){
  798. var cpopts = {};
  799. cpopts['userId'] = parseInt(user.spreadId);
  800. let spreadList = yield this.app.models.Player.findMongoAsync(cpopts, 'spreadCount spreadRebate', { sort: { stime: 1 } });//
  801. if(spreadList.length == 1){
  802. spreadList[0].spreadCount += 1;
  803. spreadList[0].spreadRebate += 100;
  804. yield spreadList[0].saveAsync();
  805. }
  806. }
  807. }
  808. yield this.lsetReabte.updateDaterebateRecord(this.agentId,this.etime);
  809. // if(this.agentId) //正常结束的才能算
  810. // {
  811. // if(this.agentRebate>0)
  812. // {
  813. // //console.warn("代理返利写分+++++");
  814. // let gameCost2=this.agentRebate;//游戏消耗
  815. // let agentRebate2=parseInt(this.agentRebate*this.rEBATERATE);
  816. // this.agentRebate=0;
  817. // var today = new Date();
  818. // today.setHours(0);
  819. // today.setMinutes(0);
  820. // today.setSeconds(0);
  821. // today.setMilliseconds(0);
  822. // let nowverifyDate=today.getTime();
  823. // var agenter = yield this.app.models.Agenter.findByIdAsync(this.agentId,'rebateOther rebateCount rebateAll rebateNow rebateOut verifyDate verifyRebate agentRate');
  824. // if (agenter)
  825. // {
  826. // //日结算
  827. // let verifyBool=false;
  828. // let verifyDate=0;
  829. // let verifyRebate=0;
  830. // //日奖励
  831. // let dateAgentRate=0;
  832. // let dateRebate=0;
  833. // if(agenter.verifyRebate>0 && agenter.verifyDate!=nowverifyDate)
  834. // {
  835. // verifyBool=true;
  836. // verifyDate=agenter.verifyDate;
  837. // verifyRebate=agenter.verifyRebate;
  838. // dateAgentRate=agenter.agentRate;
  839. // agenter.rebateNow += verifyRebate;
  840. // agenter.rebateNow += dateRebate;
  841. // agenter.rebateOther += dateRebate;
  842. // agenter.rebateCount += dateRebate;
  843. // agenter.verifyRebate=0;
  844. // }
  845. // //修改代理数据
  846. // agenter.rebateCount += agentRebate2;
  847. // agenter.rebateAll += agentRebate2;
  848. // agenter.verifyDate=nowverifyDate;
  849. // agenter.verifyRebate+= agentRebate2;
  850. // let rCount=agenter.rebateCount;
  851. // let rOther=agenter.rebateOther;
  852. // let rAll=agenter.rebateAll;
  853. // let rNow=agenter.rebateNow;
  854. // let rOut=agenter.rebateOut;
  855. // let rVerifyDate=agenter.verifyDate;
  856. // let rVerifyRebate=agenter.verifyRebate;
  857. // yield agenter.saveAsync();
  858. // // console.warn("代理返利写分+++++agenter.saveAsync()");
  859. // // 锁定返利记录
  860. // if(verifyBool && verifyRebate>0)
  861. // {
  862. // var verifyrebateRecord = new this.app.models.RebateRecord({
  863. // _id: uuid.v1(),
  864. // agentId:this.agentId,
  865. // tableId: '',
  866. // rType: 3,
  867. // rCount: rCount- agentRebate2,
  868. // rOther: rOther,
  869. // rAll: rAll- agentRebate2,
  870. // rNow: rNow,
  871. // rOut: rOut,
  872. // rSwap: verifyRebate,
  873. // rDateSwap: dateRebate,
  874. // rVerifyDate: verifyDate,
  875. // rVerifyRebate: 0
  876. // });
  877. // yield verifyrebateRecord.saveAsync();
  878. // var daterebateRecord = new this.app.models.DateRebateRecord({
  879. // _id: uuid.v1(),
  880. // agentId:this.agentId,
  881. // verifyDate: verifyDate,
  882. // verifyRebate: verifyRebate,
  883. // dateAgentRate: dateAgentRate,
  884. // dateRebate: dateRebate
  885. // });
  886. // yield daterebateRecord.saveAsync();
  887. // }
  888. // // 返利记录
  889. // var rebateRecord = new this.app.models.RebateRecord({
  890. // _id: uuid.v1(),
  891. // agentId:this.agentId,
  892. // tableId: this.recordid,
  893. // rType: 1,
  894. // rCount: rCount,
  895. // rOther: rOther,
  896. // rAll: rAll,
  897. // rNow: rNow,
  898. // rOut: rOut,
  899. // rSwap: agentRebate2,
  900. // rDateSwap: 0,
  901. // rVerifyDate: rVerifyDate,
  902. // rVerifyRebate: rVerifyRebate
  903. // });
  904. // yield rebateRecord.saveAsync();
  905. // // console.warn("返利记录+++++rebateRecord.saveAsync()");
  906. // }
  907. // }
  908. // let gameRebate=0;
  909. // if(this.isGameOk)
  910. // {
  911. // gameRebate=parseInt(this.cost*this.rEBATERATE);
  912. // }
  913. // var today = new Date();
  914. // today.setHours(0);
  915. // today.setMinutes(0);
  916. // today.setSeconds(0);
  917. // today.setMilliseconds(0);
  918. // let date=today.getTime();
  919. // let countid=this.agentId+'-'+user.userId+'-'+date;
  920. // var playercount = yield this.app.models.PlayerCount.findByIdAsync(countid,'gameCount gameCost agentRebate time');
  921. // if (playercount)
  922. // {
  923. // playercount.gameCount+=1;
  924. // playercount.gameCost+=this.cost;
  925. // playercount.agentRebate+=gameRebate;
  926. // playercount.time=Date.now();
  927. // }
  928. // else
  929. // {
  930. // playercount = new this.app.models.PlayerCount({
  931. // _id: countid,
  932. // agentId:this.agentId,
  933. // playerId: user.id,
  934. // userId: user.userId,
  935. // name: user.name,
  936. // date: date,
  937. // gameCount: 1,
  938. // gameCost: this.cost,
  939. // agentRebate: gameRebate,
  940. // time:Date.now()
  941. // });
  942. // }
  943. // yield playercount.saveAsync();
  944. // }
  945. // console.warn("活动奖励 下面开始进行判断 ",user.spreadId,user.registerTime,user.lastLoginTime);
  946. // let str11 = "hdjl xmksjxpd "+ this.id + " isGameOk: " + this.isGameOk + " userId: " + user.userId + " spreadId: " + user.spreadId + " registerTime: " + user.registerTime + " lastLoginTime: " + user.lastLoginTime ;
  947. // logger.warn(str11);////cssj
  948. // if(this.isGameOk && this.ccount == 4 && user.spreadId)//活动奖励
  949. // {
  950. // // console.warn("活动奖励 至此是游戏正常结束而且玩家有推荐id",user.spreadId,user.registerTime,user.lastLoginTime);
  951. // ////正常结束而且该玩家有推荐人id
  952. // let acSTime = 1601481600000;////20201001零点的时间戳,活动开始时间
  953. // let acETime = acSTime + 86400000*8;////20201008这天截止的时间戳 活动结束时间
  954. // let xzsjc = Date.now();
  955. // let str12 = "hdjl zcyxszcjseqwjytjr "+this.id + " userId: " + user.userId +" xzsjc: "+xzsjc;
  956. // logger.warn(str12);////cssj
  957. // if(xzsjc >= acSTime && xzsjc < acETime){
  958. // if((user.registerTime >= acSTime && user.registerTime < acETime) || user.lastLoginTime < 1598889600000){
  959. // // console.warn("活动奖励 至此该玩家是新用户",user.spreadId,user.registerTime,user.lastLoginTime);
  960. // let str13 = "hdjl zcgwjsxyh "+this.id + " userId: " + user.userId;
  961. // logger.warn(str13);////cssj
  962. // ////活动期间注册或者9月1号10月1日之间未登陆过的玩家
  963. // var todayTL = new Date();
  964. // todayTL.setHours(0);
  965. // todayTL.setMinutes(0);
  966. // todayTL.setSeconds(0);
  967. // todayTL.setMilliseconds(0);
  968. // let jrldsjc=todayTL.getTime();////今日零点时间戳
  969. // let jrjssjc=jrldsjc + 86400000;////今日结束时间戳
  970. // var opts = { stime: { $gte: jrldsjc, $lt: jrjssjc },type: { $gte: 1, $lt: 2 }};
  971. // opts['sid'] = user.id;
  972. // let acrlist = yield this.app.models.ActiveRewardRecord.findMongoAsync(opts, '_id rewardtype totalfee type sid rid gameCount stime succtime succState', { sort: { stime: 1 } });//
  973. // if(acrlist.length == 0){
  974. // // console.warn("活动奖励 活动期间今日该玩家产生新的记录",user.spreadId,user.registerTime,user.lastLoginTime);
  975. // let str14 = "hdjl hdqjjrgwjcsxdjl "+this.id + " userId: " + user.userId;
  976. // logger.warn(str14);////cssj
  977. // ////活动期间今日该玩家产生新的记录
  978. // var activerewardrec = new this.app.models.ActiveRewardRecord({
  979. // _id: uuid.v1(), // UUID
  980. // rewardtype: 0, // 奖励类型,0红包
  981. // totalfee: 0, // 产生金额,红包为分
  982. // type:1, //活动类型:1国庆签到2国庆邀请
  983. // sid: user.id, // 产生奖励的玩家id
  984. // sname:user.name, // 产生奖励的玩家name
  985. // suid:user.userId, // 产生奖励的玩家userId
  986. // rid: user.id, // 此条奖励的受益玩家
  987. // gameCount: 1, // 游戏局数
  988. // stime: xzsjc, // 记录产生时间
  989. // succtime: 0, // 任务完成时间,任务未完成的时候这里是0
  990. // succState: 0 // 任务是否完成的状态,0:未完成1:已达成
  991. // });
  992. // yield activerewardrec.saveAsync();
  993. // }
  994. // else{
  995. // let str15 = "hdjl hdqjjrgwjyjcsgjl "+this.id + " userId: " + user.userId;
  996. // logger.warn(str15);////cssj
  997. // ////活动期间更新今日该玩家已经产生的记录
  998. // let newre = acrlist[0];
  999. // newre.gameCount++;
  1000. // if(newre.gameCount >= 2){
  1001. // // console.warn("活动奖励 活动期间更新今日该玩家已经产生的记录",user.spreadId,user.registerTime,user.lastLoginTime);
  1002. // let str16 = "hdjl hdqjgxjrgwjyjcsdjl "+this.id + " userId: " + user.userId + " gameCount: " + newre.gameCount;
  1003. // logger.warn(str16);////cssj
  1004. // ////完成为解散2局,该玩家完成了签到的任务了
  1005. // if(newre.gameCount == 2){
  1006. // newre.totalfee = 500;
  1007. // newre.succtime = xzsjc;
  1008. // newre.succState = 1;
  1009. // }
  1010. // yield newre.saveAsync();
  1011. // }
  1012. // if(newre.gameCount == 2){
  1013. // var opts2 = { stime: { $gte: acSTime, $lt: acETime },type: { $gte: 2, $lt: 3 }};
  1014. // opts2['sid'] = user.id;
  1015. // let acrlist2 = yield this.app.models.ActiveRewardRecord.findMongoAsync(opts2, 'rid', { sort: { stime: 1 } });//
  1016. // let isneedcj = false;////是否需要创建邀请奖励产生记录
  1017. // if(acrlist2.length == 0){
  1018. // isneedcj = true;
  1019. // // if(parseInt(acrlist2[0].rid) && parseInt(acrlist2[0].rid) == user.spreadId) isneedcj = true;
  1020. // }
  1021. // // console.warn("活动奖励 完成未解散2局,该玩家的推荐人完成了邀请的任务了",user.spreadId,user.registerTime,user.lastLoginTime);
  1022. // let str17 = "hdjl csgwjdyqjl "+this.id + " userId: " + user.userId + " isneedcj: " + isneedcj;
  1023. // logger.warn(str17);////cssj
  1024. // if(isneedcj){
  1025. // ////完成为解散2局,该玩家的推荐人完成了邀请的任务了
  1026. // var activerewardrec = new this.app.models.ActiveRewardRecord({
  1027. // _id: uuid.v1(), // UUID
  1028. // rewardtype: 0, // 奖励类型,0红包
  1029. // totalfee: 500, // 产生金额,红包为分
  1030. // type:2, //活动类型:1国庆签到2国庆邀请
  1031. // sid: user.id, // 产生奖励的玩家id
  1032. // suid:user.userId, // 产生奖励的玩家userId
  1033. // sname:user.name, // 产生奖励的玩家name
  1034. // rid: user.spreadId,// 此条奖励的受益玩家
  1035. // gameCount: newre.gameCount, // 游戏局数
  1036. // stime: xzsjc, // 记录产生时间
  1037. // succtime: xzsjc, // 任务完成时间,任务未完成的时候这里是0
  1038. // succState: 1 // 任务是否完成的状态,0:未完成1:已达成
  1039. // });
  1040. // yield activerewardrec.saveAsync();
  1041. // }
  1042. // }
  1043. // }
  1044. // }
  1045. // }
  1046. // }
  1047. // let str4 = "table 222 站起桌子之后---id:%s"+this.id + " uid"+user.userId+" "+ this.state;
  1048. // logger.info(str4);////cssj
  1049. }
  1050. });
  1051. // 玩家断线
  1052. proto.offlineAsync = cor(function* (user) {
  1053. let str3 = "table 玩家断线.......id: "+ this.id + " user.chairId: " + user.chairId + " user.name: " + user.name ;
  1054. logger.warn(str3);////cssj
  1055. if (user.chairId != -1) {
  1056. //user.state = User.STATE.OFFLINE;//ts--
  1057. user.state2 = User.STATE.OFFLINE;//ts++
  1058. user.offlinetime = Date.now();//ts++断线
  1059. var channelId = 'xct:' + this.id;
  1060. yield this.app.controllers.push._quitAsync(channelId, user.id);
  1061. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.STATE_CHANGE, data: { chairId: String(user.chairId), state: String(user.state2), state2: String(user.state2) } });
  1062. // 无人在线
  1063. // console.warn("提前结算666");
  1064. //if (this.isOffline()) return this.overTimeAsync(MODE.OFFLINE);
  1065. // console.warn("玩家断线-------定时器启动");
  1066. // 计时结算
  1067. let lxjssj = 600000;//断线解散时间
  1068. if(this.lsetReabte.getIsBS(this.agentId,this.ownerName,this.ownerUid)) lxjssj = 1800000;//比赛的话有托管机制,害怕20分钟完成不了比赛所以延长时间
  1069. if (!this.endTimer) this.endTimer = this.app.timer.setTimeout(() => this.overTimeAsync(ENDMODE.OFFLINEEND),lxjssj);/////断线3分钟自动结算
  1070. // let str4 = "table 玩家断线---id:"+this.id + ",uid"+user.userId+" "+ this.state;
  1071. // logger.info(str4);////cssj
  1072. }
  1073. });
  1074. // 离开桌子
  1075. proto.leaveAsync = cor(function* (user) {
  1076. let str3 = "table 离开桌子.......id: "+ this.id + " user.chairId: " + user.chairId + " user.name: " + user.name ;
  1077. logger.warn(str3);////cssj
  1078. // this.leavePlayerID = user.id;//////TL++,旁观为房主的话离开之后由于从观战者列表里面删除了,导致发消息的时候他收不到离开桌子的消息
  1079. // console.warn("离开桌子、、、、、、、");
  1080. yield this.beforeLeaveAsync(user);
  1081. var chairId = user.chairId;
  1082. // yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.LEAVE, data: { account: user.account } });/////TL++zs,原来在下面
  1083. if (chairId != -1) {
  1084. delete this.users[chairId];
  1085. delete this.handCards[chairId];
  1086. yield this.afterStandAsync(user, chairId);
  1087. } else {
  1088. let pos = _.findIndex(this.lookers, (u) => (u.id == user.id));
  1089. if (pos != -1) this.lookers.splice(pos, 1);
  1090. }
  1091. return this.afterLeaveAsync(user);
  1092. });
  1093. // 离开桌子之前
  1094. proto.beforeLeaveAsync = cor(function* (user) {
  1095. var channelId = 'xct:' + this.id;
  1096. return this.app.controllers.push._quitAsync(channelId, user.id);
  1097. });
  1098. // 离开桌子之后
  1099. proto.afterLeaveAsync = cor(function* (user) {
  1100. // 离开通知
  1101. /////TL++zsyl 在此之前离开玩家已经从玩家列表或者旁观者列表中删除了所以把下面这句提到前面去了
  1102. return this.pushMsgAsync(-1, 'paodekuai_event', { type: M.LEAVE, data: { account: user.account } });
  1103. });
  1104. // 玩家准备
  1105. proto.readyGameAsync = cor(function* (user) {
  1106. let str3 = "table 玩家准备.......id: "+ this.id + " user.chairId: " + user.chairId + " this.over: " + this.over + " user.name: " + user.name ;
  1107. logger.warn(str3);////cssj
  1108. // let str3 = "table 玩家准备---id:"+this.id + ",uid"+user.userId+","+ this.state;
  1109. // logger.info(str3);////cssj
  1110. if(this.state==STATE.FREE2)//ts++二次空闲
  1111. {
  1112. user.state2 = User.STATE.READY;
  1113. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.STATE_CHANGE, data: { chairId: String(user.chairId), state: String(user.state2), state2: String(user.state2) } });
  1114. if (this.isReady2() && !this.isGameOk) yield this.startGameAsync();
  1115. }
  1116. else
  1117. {
  1118. user.state = User.STATE.READY;
  1119. user.state2 = User.STATE.READY;
  1120. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.STATE_CHANGE, data: { chairId: String(user.chairId), state: String(user.state2), state2: String(user.state2) } });
  1121. // console.warn("玩家准备玩家准备玩家准备 ",this.isReady() ,this.isGameOver());
  1122. if (this.isReady() && !this.isGameOk) yield this.startGameAsync();
  1123. }
  1124. // let str4 = "table 222玩家准备---id:"+this.id + ",uid"+user.userId+","+ this.state;
  1125. // logger.info(str4);////cssj
  1126. return { code: C.OK };
  1127. });
  1128. // 开始游戏
  1129. proto.startGameAsync = cor(function* () {
  1130. //this.backStartTimer = null;//////重入之后系统会自动准备为了解决可能没牌的问题2秒之后才开始游戏
  1131. let str4 = "table 开始游戏---id:"+this.id +" ,state "+ this.state +" 当前局 "+ (this.over+1);
  1132. if(this.autoReadyTimer2)
  1133. {
  1134. clearTimeout(this.autoReadyTimer2);
  1135. this.autoReadyTimer2 = null;
  1136. }
  1137. let cd = {id:this.id, agentId:this.agentId}
  1138. this.app.rpc.hall.hallRemote.delTable.toServer("hall-server-1", cd, () => { });
  1139. logger.warn(str4);////cssj
  1140. if(this.isYJKSGL){
  1141. return;
  1142. }
  1143. this.isYJKSGL = true;/////是否已经执行过开始函数了
  1144. this.isYJJSGL = false;/////是否已经执行过结算函数了
  1145. if(this.backStartTimer)
  1146. {
  1147. clearTimeout(this.backStartTimer);
  1148. this.backStartTimer = null;
  1149. }
  1150. // 状态设置
  1151. this.state = STATE.PLAYING;
  1152. //ts++设置为游戏状态
  1153. for (let user of this.users)
  1154. {
  1155. if (user) {
  1156. if(user.state == User.STATE.PLAYING)//ts++已经开始
  1157. {
  1158. if(user.state2 == User.STATE.READY)
  1159. {
  1160. user.state2 = User.STATE.PLAYING
  1161. user.offlinetime = 0;
  1162. }
  1163. }
  1164. else//ts++第一次开始
  1165. {
  1166. user.state = User.STATE.PLAYING
  1167. user.state2 = User.STATE.PLAYING
  1168. user.offlinetime = 0;
  1169. }
  1170. }
  1171. }
  1172. //ts++end
  1173. let whdata = yield this.app.models.WHstate.findByIdReadOnlyAsync('wh', 'rebaterate yxndlbTime yxndlbTip');
  1174. // console.warn("22检查是否维护状态",whdata);
  1175. if (whdata) {
  1176. if(whdata.yxndlbTime) this.yxndlbTime = whdata.yxndlbTime;
  1177. if(whdata.yxndlbTip) this.yxndlbTip = whdata.yxndlbTip;
  1178. }
  1179. this.PaijuHuiFang = [];////TL++,牌局回放 重置数据
  1180. // 初始信息
  1181. if (this.over <= 0) {///////本房间开始的第一局游戏
  1182. this.stime = Date.now();
  1183. this.chBanker = 0;
  1184. this.pjhffileName[this.pjhffileName.length] = this.PJHF.getjsonFileName(0,this.recordid,this.ctime);/////TL++,用于记录玩家牌局回放的json文件名
  1185. // console.error("000HHHHHHHHHHHHHHHHHHHHHH",this.pjhffileName.length,this.pjhffileName);
  1186. this.PJHF.writePJHFJson(this.getTableInfo(),0,this.id);////在开始第一局的时候将桌子信息写入本地的json文件
  1187. this.isNeverStart = false;/////TL++,游戏是否从未开始
  1188. }
  1189. this.gameNeverStart = false;/////TL++,游戏是否从未开始过,用于解散房间判断
  1190. // 发手牌 把这句提前是为了洗牌之后能拿到百搭牌在游戏开始的时候给客户端发过去
  1191. var handCards = this.logic.handCards(this.chBanker,this.PJHF,this.over,this.recordid,this.ctime);
  1192. if (this.over <= 0) {///////本房间开始的第一局游戏
  1193. this.chBanker = this.logic.getSCId(handCards);
  1194. }
  1195. this.currentId = this.chBanker;
  1196. //console.warn("ccccccccccccccccccccc当局的currentId ",this.currentId);
  1197. let scoreListTL = []
  1198. for (let i = 0; i < this.users.length; ++i) {
  1199. let user = this.users[i];
  1200. if (user) {
  1201. let score = this.score.getScore(user.id);
  1202. scoreListTL[i] = score
  1203. }
  1204. }
  1205. // 掷骰子
  1206. var sttGame = {
  1207. banker: String(this.chBanker),
  1208. stime: String(Date.now() - this.stime),
  1209. setCardFileName: String(this.logic.setCardFileName),////TL++设置手牌的文件名
  1210. scoreListTL:scoreListTL,/////TL++,每个玩家当前的分数列表
  1211. yxndlbTime:this.yxndlbTime,
  1212. yxndlbTip:this.yxndlbTip,
  1213. };
  1214. // console.warn("游侠开始*******************this.chBanker",this.chBanker);
  1215. this.setPaijuHuiFangData(M.START_GAME,sttGame);/////TL++ 牌局回放 push游戏开始
  1216. // 开始通知
  1217. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.START_GAME, data: sttGame });
  1218. this.isHTSSC = (this.over <= 0 && handCards[this.currentId].cards.indexOf(103) != -1);//是否是黑桃三首出
  1219. // console.warn("发牌通知 是否是黑桃三首出 "+this.isHTSSC+" currentId "+this.currentId);
  1220. this.tipInfo.chairId = this.currentId;//出牌提示
  1221. this.tipInfo.tipCards = this.logic.getOutTip(this.currentId,handCards[this.currentId].cards,this.lastOut,this.isHTSSC,this.nextCardCount == 1);
  1222. ////// 发手牌原来在这里
  1223. var lastCount = this.logic.leaveCount();/////TL++
  1224. for (let i = 0; i < handCards.length; ++i) {
  1225. this.handCards[i] = handCards[i].cards;/////TL++zsyl
  1226. let tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  1227. if(i == this.currentId) tipInfo = this.tipInfo;
  1228. let scards = {
  1229. cards: handCards[i].cards,
  1230. currentId: this.currentId,
  1231. tipInfo: this.logic.deepCloneTL(tipInfo),
  1232. lastCount: String(lastCount),
  1233. dczsList: this.logic.getDCZSList(i),
  1234. jpqsysj: this.logic.everyJPQSYSJ[i],
  1235. isAutoOut:this.everyIsAutoOut[i]
  1236. };
  1237. if(this.isHTSFB && handCards[i].cards.indexOf(210) != -1) this.zhaniaoChair = i;
  1238. // 发牌通知
  1239. // console.error("sscc发牌通知 4条应该=================",i,handCards.lengt);
  1240. yield this.pushMsgAsync(i, 'paodekuai_event', { type: M.SEND_CARD, data: scards });
  1241. }
  1242. let pjhfsplist = {
  1243. shouPai:this.logic.deepCloneTL(this.handCards),
  1244. currentId: this.currentId,
  1245. // maskList:this.logic.deepCloneTL(this.masks),/////TL++,10月28号,为了实现能看到每个玩家的操作
  1246. lastCount:String(this.logic.leaveCount())
  1247. }
  1248. this.setPaijuHuiFangData(M.SEND_CARD,pjhfsplist);/////TL++ 牌局回放 push发牌数据
  1249. // 围观通知
  1250. var cardCounts = _.fill(Array(this.ccount), 0);
  1251. for (let i = 0; i < cardCounts.length; ++i) {
  1252. cardCounts[i] = this.handCards[i].length;
  1253. }
  1254. yield this.lookMsgAsync('paodekuai_event', { type: M.SEND_CARD, data: { currentId: this.currentId,cardCounts: cardCounts, lastCount: String(lastCount) } });
  1255. let str3 = "table 222开始游戏---id:"+this.id +","+ this.state;
  1256. logger.warn(str3);////cssj
  1257. yield this.autoOutCard(this.currentId);
  1258. return { code: C.OK };
  1259. });
  1260. // 出牌
  1261. proto.outCardAsync = cor(function* (chairId, cards) {
  1262. cards = this.logic.sort(cards)
  1263. let str3 = "table 出牌---id:"+this.id + " ,uid "+chairId+" cards "+cards;
  1264. logger.warn(str3);////cssj
  1265. // if(this.autoOutTimer)
  1266. // {
  1267. // clearTimeout(this.autoOutTimer);
  1268. // this.autoOutTimer = null;
  1269. // }
  1270. // console.warn("出牌出剖出牌",chairId,this.buhuaTimeout);///// 您正在补花,请稍后出牌。/////TL++,正在补花的时候不允许玩家出牌
  1271. // 校验顺序
  1272. if (this.currentId != chairId) {
  1273. return { code: C.FAILD, msg: C.TABLE_TURN_ERROR };
  1274. }
  1275. let ccards = this.logic.deepCloneTL(cards);
  1276. ccards = _.uniq(ccards);
  1277. if(ccards.length != cards.length) return { code: C.FAILD, msg: C.TABLE_CARD_ERROR };//出的牌有重复
  1278. // console.warn("出牌删除手牌之前 "+this.handCards[chairId]);
  1279. if(this.isYBQZDCP){
  1280. }
  1281. if(cards.length == 1 && this.nextCardCount == 1){
  1282. let maxDanList = this.logic.getMaxDanList(this.handCards[chairId]);
  1283. if(maxDanList.indexOf(cards[0]) == -1) {
  1284. // "下家只剩下1张了,如果打单牌请打出最大的单牌!"
  1285. return { code: C.FAILD, msg: C.TYPE_IS_WRONG };
  1286. }
  1287. }
  1288. // 得到出牌牌型
  1289. let type = this.logic.getCardsType(cards,this.lastOut,this.handCards[chairId],this.isHTSSC,this.tipInfo.tipCards);
  1290. // console.warn("得到出牌牌型 "+type + " "+this.logic.styleTL.ERROR+" cards "+cards);
  1291. if(type == this.logic.styleTL.ERROR) return { code: C.FAILD, msg: C.TYPE_IS_WRONG };//牌型不存在
  1292. else if(type == this.logic.styleTL.NULL) return { code: C.FAILD, msg: C.PLAYER_POKE_WRONG };//牌型合法但是大不过
  1293. else if(type == -2) return { code: C.FAILD, msg: C.TABLE_CANOUTMUSTOUT };//自己有能大过上家出牌的牌不能不出牌(出[])
  1294. else if(type == -3) return { code: C.FAILD, msg: C.TABLE_HTSSCMYHTS };//黑桃三首出所出的牌没有黑桃三
  1295. else if(type == -4) return { code: C.FAILD, msg: C.TABLE_ZDBKCSCDPBNYZD };//炸弹不可拆时出的牌不能带炸弹
  1296. // 删除手牌
  1297. if (!this.logic.remove(this.handCards[chairId], cards)) {
  1298. return { code: C.FAILD, msg: C.TABLE_CARD_ERROR };
  1299. }
  1300. //至此所出的牌合法的(要么要不起要么能大过)
  1301. if(this.autoOutTimer)
  1302. {
  1303. clearTimeout(this.autoOutTimer);
  1304. this.autoOutTimer = null;
  1305. }
  1306. this.logic.setDCZSList(cards);
  1307. this.logic.chuPaiTL()////TL++,统计出牌个数,为了判断天胡和地胡
  1308. // console.warn("出牌删除手牌之后 "+this.handCards[chairId]);
  1309. this.outCard = cards;
  1310. this.outerId = chairId;
  1311. this.outCards[chairId].push(cards);
  1312. this.bloutCard[chairId] = cards;
  1313. let scyxcpChair = this.lastOut.chair;
  1314. if(this.isHTSSC) this.isHTSSC = false;
  1315. let isblEnd = false;//本轮是否结束
  1316. let newcu = -10;//新一轮的当前玩家
  1317. if(cards.length > 0){
  1318. this.lastOut = {chair:chairId,type:type,cards:this.logic.deepCloneTL(cards)};//上次有效的出牌(要不起出的[]不算有效出牌)
  1319. if(type == this.logic.styleTL.ZHADAN){
  1320. this.blZDInfo[this.blZDInfo.length-1] = [chairId,this.logic.getValuepx(cards[0])];
  1321. }
  1322. }
  1323. else{
  1324. let byCount = 0;//要不起玩家个数
  1325. let yCount = 0;//要的玩家个数
  1326. for (let i = 0; i < this.bloutCard.length; ++i) {
  1327. if(this.bloutCard[i] == null) break;
  1328. if(this.bloutCard[i].length == 0) byCount++;
  1329. else if(this.bloutCard[i].length > 0){
  1330. yCount++;
  1331. newcu = i;
  1332. }
  1333. }
  1334. if(byCount == this.ccount - 1 && yCount == 1) isblEnd = true;
  1335. else newcu = -10;
  1336. }
  1337. if(isblEnd){
  1338. this.currentId = -1;
  1339. this.lastOut = {chair:-1,type:-1,cards:[]};//上次有效的出牌(要不起出的[]不算有效出牌)
  1340. if(this.blZDInfo[this.blZDInfo.length-1].length > 0){
  1341. //已经有记录到有效的炸弹了
  1342. this.blZDInfo[this.blZDInfo.length] = [];
  1343. }
  1344. }
  1345. else{
  1346. this.currentId = (chairId + 1) % this.ccount;
  1347. this.bloutCard[this.currentId] = null;
  1348. }
  1349. if(this.handCards[chairId].length == 0){
  1350. //有人出完了
  1351. this.winner.chs[0] = chairId;
  1352. isblEnd = true;
  1353. newcu = chairId;
  1354. this.currentId = -1;
  1355. }
  1356. let isMZYBQZDCP = false;//是否满足要不起自动出牌
  1357. if(this.currentId > -1){
  1358. let next = (this.currentId + 1) % this.ccount;
  1359. this.nextCardCount = this.handCards[next].length;
  1360. this.tipInfo.chairId = this.currentId;//出牌提示
  1361. this.tipInfo.tipCards = this.logic.getOutTip(this.currentId,this.handCards[this.currentId],this.lastOut,this.isHTSSC,this.nextCardCount == 1);
  1362. // console.warn("这里获取了出牌提示111 "+this.currentId);
  1363. if(this.isYBQZDCP && this.tipInfo.tipCards.length == 0) isMZYBQZDCP = true;//是否要不起自动出牌
  1364. }
  1365. else{
  1366. this.tipInfo = {chairId:-1,tipCards:[]};
  1367. }
  1368. for (let i = 0; i < this.ccount; ++i) {
  1369. let ocard = { //这必须写for循环里面
  1370. chairId: String(chairId),
  1371. currentId: this.currentId,
  1372. isblEnd: false,
  1373. lastChair: scyxcpChair,
  1374. nextCardCount: this.nextCardCount,
  1375. type: String(type),
  1376. outerLast: this.handCards[chairId].length,
  1377. isAutoOut: this.everyIsAutoOut[chairId],
  1378. dczsList: this.logic.getDCZSList(i),
  1379. cards: cards
  1380. };
  1381. let tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  1382. if(i == this.currentId) {
  1383. tipInfo = this.tipInfo;
  1384. // console.warn("是这里发的消息嘛 " + JSON.stringify(tipInfo));
  1385. }
  1386. ocard.tipInfo = this.logic.deepCloneTL(tipInfo);
  1387. yield this.pushMsgAsync(i, 'paodekuai_event', { type: M.OUT_CARD, data: ocard });
  1388. if(i == this.ccount - 1){
  1389. let cocard = this.logic.deepCloneTL(ocard);
  1390. cocard.tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  1391. yield this.lookMsgAsync('paodekuai_event', { type: M.OUT_CARD, data: cocard });
  1392. let pjhfsplist ={
  1393. shouPai:this.logic.deepCloneTL(this.handCards),
  1394. // lastCount:String(this.logic.leaveCount()),
  1395. ocard:this.logic.deepCloneTL(cocard),
  1396. outCards:this.logic.deepCloneTL(this.outCards),
  1397. }
  1398. this.setPaijuHuiFangData(M.OUT_CARD,pjhfsplist);/////TL++ 牌局回放 push出牌数据
  1399. }
  1400. }
  1401. let str4 = "table end出牌---id:"+this.id + " ,uid "+chairId +" cards "+cards+" "+isMZYBQZDCP+" "+isblEnd +" "+ newcu;
  1402. logger.warn(str4);////cssj
  1403. // console.warn(" 能否进入下一轮 ",isMZYBQZDCP,isblEnd , newcu);
  1404. if(isMZYBQZDCP || (isblEnd && newcu > -1)){
  1405. // console.warn(" 进入下一轮111 ",isMZYBQZDCP,isblEnd , newcu);
  1406. if(!this.ksNewLunTimer){
  1407. this.ksNewLunTimer = this.app.timer.setTimeout(() =>
  1408. {
  1409. // console.warn(" 进入下一轮222 ",isMZYBQZDCP,isblEnd , newcu);
  1410. let str44 = "table end出牌---进入下一轮222id:"+this.id + " ,uid "+chairId +" cards "+cards+" "+isMZYBQZDCP+" "+isblEnd +" "+ newcu;
  1411. logger.warn(str44);////cssj
  1412. if(this.ksNewLunTimer)
  1413. {
  1414. clearTimeout(this.ksNewLunTimer);
  1415. this.ksNewLunTimer = null;
  1416. }
  1417. let isEnd = false;
  1418. for (let i = 0; i < this.handCards.length; ++i) {
  1419. if(this.handCards[i].length == 0){
  1420. isEnd = true;
  1421. break;
  1422. }
  1423. }
  1424. if(isEnd){
  1425. return this.dyjshs();//调用结束函数
  1426. }
  1427. else{
  1428. if(isMZYBQZDCP){
  1429. if(this.currentId > -1){
  1430. let str5 = "table 要不起在这里自动出牌了---id:"+this.id + " ,uid "+this.currentId ;
  1431. logger.warn(str5);////cssj
  1432. // console.error("要不起在这里自动出牌了");
  1433. this.outCardAsync(this.currentId,[])
  1434. }
  1435. else{
  1436. console.error("要不起自动出牌这里错了");
  1437. let str5 = "table 要不起自动出牌这里错了---id:"+this.id + " ,uid "+this.currentId ;
  1438. logger.warn(str5);////cssj
  1439. }
  1440. return { code: C.OK };
  1441. }
  1442. this.ksNewLunOut(newcu)
  1443. return { code: C.OK };
  1444. }
  1445. }
  1446. , 1000);//各玩家均没有操作的情况下延迟2秒更新杠后两张牌的状态
  1447. }
  1448. }
  1449. else{
  1450. if(this.currentId > -1){
  1451. // console.warn("在这里判断是否可以一把出完了 111 ")
  1452. let outList = this.logic.getCanOutOverList(this.currentId,this.handCards[this.currentId],this.tipInfo,this.lastOut)
  1453. if(outList.length > 0){
  1454. // console.warn("在这里可以一把出完了111 "+JSON.stringify(outList));
  1455. yield this.autoOutLastCard(this.currentId,outList);
  1456. return { code: C.OK };
  1457. }
  1458. else{
  1459. yield this.autoOutCard(this.currentId);
  1460. }
  1461. }
  1462. }
  1463. return { code: C.OK };
  1464. });
  1465. proto.autoOutLastCard = cor(function* (chair,cards) {
  1466. if(!this.autoOutLastTimer){
  1467. this.autoOutLastTimer = this.app.timer.setTimeout(() =>
  1468. {
  1469. // console.warn(" 进入下一轮222 ",isMZYBQZDCP,isblEnd , newcu);
  1470. let str44 = "table 自动出掉最后一手 id:"+this.id + " ,uid "+chair +" cards "+cards;
  1471. logger.warn(str44);////cssj
  1472. if(this.autoOutLastTimer)
  1473. {
  1474. clearTimeout(this.autoOutLastTimer);
  1475. this.autoOutLastTimer = null;
  1476. }
  1477. this.outCardAsync(chair,cards)
  1478. }
  1479. , 100);//最后一手牌可以出完的时候1秒后自动出掉
  1480. }
  1481. return { code: C.OK };
  1482. });
  1483. //调用结算函数,因为定时器里不能yield,所以改成这种方式
  1484. proto.dyjshs = cor(function* () {
  1485. yield this.concludeGameAsync(MODE.NORMAL);
  1486. });
  1487. proto.ksNewLunOut = cor(function* (newcu) {
  1488. this.currentId = newcu;
  1489. this.bloutCard = this.logic.fillDeep(Array(this.ccount),null);;////目前本轮每个玩家的出牌[]表示该玩家过牌,null表示本轮该玩家还未出牌
  1490. if(this.currentId > -1){
  1491. // console.warn("这里获取了出牌提示222 "+this.currentId);
  1492. let next = (this.currentId + 1) % this.ccount;
  1493. this.nextCardCount = this.handCards[next].length;
  1494. this.tipInfo.chairId = this.currentId;//出牌提示
  1495. this.tipInfo.tipCards = this.logic.getOutTip(this.currentId,this.handCards[this.currentId],this.lastOut,this.isHTSSC,this.nextCardCount == 1);
  1496. }
  1497. for (let i = 0; i < this.ccount; ++i) {
  1498. let ocard2 = {
  1499. chairId: String(-1),
  1500. currentId: this.currentId,
  1501. isblEnd: true,
  1502. lastChair: this.lastOut.chair,
  1503. nextCardCount: this.nextCardCount,
  1504. type: String(-1),
  1505. cards: []
  1506. };
  1507. let tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  1508. if(i == this.currentId) tipInfo = this.tipInfo;
  1509. ocard2.tipInfo = this.logic.deepCloneTL(tipInfo);
  1510. // console.warn("这里发给前端了 "+JSON.stringify(ocard2.tipInfo));
  1511. yield this.pushMsgAsync(i, 'paodekuai_event', { type: M.OUT_CARD, data: ocard2 });
  1512. if( i == this.ccount -1){
  1513. let cocard2 = this.logic.deepCloneTL(ocard2);
  1514. cocard2.tipInfo = {chairId:-1,tipCards:[]}//出牌提示
  1515. let pjhfsplist2 ={
  1516. shouPai:this.logic.deepCloneTL(this.handCards),
  1517. // lastCount:String(this.logic.leaveCount()),
  1518. ocard:this.logic.deepCloneTL(cocard2),
  1519. outCards:this.logic.deepCloneTL(this.outCards),
  1520. }
  1521. yield this.lookMsgAsync('paodekuai_event', { type: M.OUT_CARD, data: ocard2 });
  1522. this.setPaijuHuiFangData(M.OUT_CARD,pjhfsplist2);/////TL++ 牌局回放 push出牌数据
  1523. }
  1524. }
  1525. let str4 = "table 开始新一轮出牌---id:"+this.id + " ,uid -1" +" cards ";
  1526. logger.warn(str4);////cssj
  1527. if(this.currentId > -1){
  1528. // console.warn("在这里判断是否可以一把出完了 222 ")
  1529. let outList = this.logic.getCanOutOverList(this.currentId,this.handCards[this.currentId],this.tipInfo,this.lastOut)
  1530. if(outList.length > 0){
  1531. // console.warn("在这里可以一把出完了222 "+JSON.stringify(outList));
  1532. yield this.autoOutLastCard(this.currentId,outList);
  1533. return { code: C.OK };
  1534. }
  1535. else {
  1536. yield this.autoOutCard(this.currentId);
  1537. return { code: C.OK };
  1538. }
  1539. }
  1540. })
  1541. proto.findAutoCards = cor(function* (currentId,_outIndex) {
  1542. let cards = null;
  1543. let outIndex = _outIndex;
  1544. if(this.tipInfo.chairId == currentId && this.tipInfo.tipCards.length > 0){
  1545. cards = this.logic.deepCloneTL(this.tipInfo.tipCards[outIndex]);
  1546. }
  1547. let cpishf = true;//出牌是否合法
  1548. if(cards && cards.length > 0){
  1549. let cpres = this.outCardAsync(currentId,cards);
  1550. //{"isFulfilled":true,"isRejected":false,"fulfillmentValue":{"code":201,"msg":"332"}}
  1551. _.forEach(cpres, function(value, key) {
  1552. // console.warn("key "+key+" value "+JSON.stringify(value));
  1553. if(key == "_settledValue"){
  1554. // console.warn("_settledValue key "+key+" value "+JSON.stringify(value));
  1555. if(value && value.code && value.code != C.OK){
  1556. cpishf = false;
  1557. // console.error("自动出牌不合法 cpishf "+cpishf);
  1558. }
  1559. return;
  1560. }
  1561. })
  1562. }
  1563. if(!cpishf){
  1564. // console.error("自动出牌失败 id:"+this.id+" currentId "+currentId+" " +JSON.stringify(cards));
  1565. outIndex++;
  1566. this.findAutoCards(currentId,outIndex);
  1567. }
  1568. // else console.warn("自动出牌成功 id: "+this.id+" currentId "+currentId+" "+JSON.stringify(cards));
  1569. })
  1570. proto.autoOutCard = cor(function* (currentId) {
  1571. let cpdjs = -1;//自动出牌倒计时
  1572. if(this.lsetReabte.getIsBS(this.agentId,this.ownerName,this.ownerUid)) {
  1573. //是比赛链接
  1574. cpdjs = 20;//20秒后进入托管
  1575. if(this.everyIsAutoOut[currentId]) cpdjs = 2;//已经是托管的话2秒之后自动出牌
  1576. }
  1577. if(this.autoOutTimer)
  1578. {
  1579. clearTimeout(this.autoOutTimer);
  1580. this.autoOutTimer = null;
  1581. }
  1582. // console.warn("判断是否进入托管 currentId "+currentId+" isauto "+this.everyIsAutoOut[currentId]+" cpdjs "+cpdjs);
  1583. let cards = null;
  1584. let outIndex = 0;
  1585. if(this.tipInfo.chairId == currentId && this.tipInfo.tipCards.length > 0){
  1586. cards = this.logic.deepCloneTL(this.tipInfo.tipCards[0]);
  1587. }
  1588. if(cpdjs > 0 && cards && cards.length > 0){
  1589. this.autoOutTimer = this.app.timer.setTimeout(() =>
  1590. {
  1591. let str44 = "table 自动出掉 id:"+this.id + " ,uid "+currentId +" cpdjs "+cpdjs+" cards "+cards;
  1592. logger.warn(str44);////cssj
  1593. this.everyIsAutoOut[currentId] = 1;
  1594. // 下面是修改之后的
  1595. this.findAutoCards(currentId,0);
  1596. // 下面是修改之前的
  1597. // let cpres = this.outCardAsync(currentId,cards);
  1598. // //{"isFulfilled":true,"isRejected":false,"fulfillmentValue":{"code":201,"msg":"332"}}
  1599. // let cpishf = true;//出牌是否合法
  1600. // _.forEach(cpres, function(value, key) {
  1601. // // console.warn("key "+key+" value "+JSON.stringify(value));
  1602. // if(key == "_settledValue"){
  1603. // // console.warn("_settledValue key "+key+" value "+JSON.stringify(value));
  1604. // if(value && value.code && value.code != C.OK){
  1605. // cpishf = false;
  1606. // // console.error("自动出牌不合法 cpishf "+cpishf);
  1607. // }
  1608. // return;
  1609. // }
  1610. // });
  1611. // // console.warn("自动出牌返回 "+ typeof(cpres)+" "+JSON.stringify(cpres)+" "+JSON.stringify(cpres.isFulfilled)+" "+JSON.stringify(cpres.fulfillmentValue));
  1612. // if(!cpishf){
  1613. // console.error("自动出牌失败 id:"+this.id+" currentId "+currentId+" " +JSON.stringify(cards));
  1614. // outIndex++;
  1615. // if(this.tipInfo.tipCards[outIndex]){
  1616. // let cpres2 = this.outCardAsync(currentId,this.tipInfo.tipCards[outIndex])
  1617. // }
  1618. // }
  1619. // else console.warn("自动出牌成功 "+JSON.stringify(cards));
  1620. }
  1621. , cpdjs*1000);//最后一手牌可以出完的时候1秒后自动出掉
  1622. }
  1623. return { code: C.OK };
  1624. })
  1625. // 操作是否自动出牌
  1626. proto.autoOutCardAsync = cor(function* (chairId) {
  1627. // console.warn("操作是否自动出牌 "+chairId+" "+ this.everyIsAutoOut[chairId]+" this.currentId "+this.currentId);
  1628. if(this.everyIsAutoOut[chairId]) {
  1629. this.everyIsAutoOut[chairId] = 0;
  1630. // if(this.currentId == chairId && this.autoOutTimer)
  1631. // {
  1632. // clearTimeout(this.autoOutTimer);
  1633. // this.autoOutTimer = null;
  1634. // }
  1635. }
  1636. else {
  1637. //比赛链接目前不允许开启托管
  1638. if(!this.lsetReabte.getIsBS(this.agentId,this.ownerName,this.ownerUid)) {
  1639. this.everyIsAutoOut[chairId] = 1;
  1640. }
  1641. }
  1642. let data = {isAutoOut:this.everyIsAutoOut[chairId]}
  1643. return { code: C.OK, data: data };
  1644. })
  1645. // 结算游戏
  1646. proto.concludeGameAsync = cor(function* (mode) {
  1647. /////增加下面这几行是为了保证每一把只执行一次结算方法
  1648. if(this.isYJJSGL){
  1649. // let strk = "table 结算游戏 id:了保证每一把只执行一次结算方法 "+this.id +"结算模式"+mode
  1650. // logger.info(strk);////cssj
  1651. return;
  1652. }
  1653. this.isYJJSGL = true;
  1654. this.isYJKSGL = false;/////是否已经执行过开始函数了
  1655. // console.warn("结算函数",mode);
  1656. let str1 = "table 结算游戏 id: "+this.id +" 结算模式 "+mode
  1657. logger.warn(str1);////cssj
  1658. //ts--end
  1659. // 结算数据
  1660. var winner = this.winner;
  1661. var data = { mode: String(mode), lead: String(winner.lead) };
  1662. var wins = this.logic.fillDeep(Array(this.ccount), {
  1663. win: 0,//总输赢
  1664. lucky: 0,
  1665. isPoChan: 0,
  1666. cardfen: 0,
  1667. zhadanfen: 0,
  1668. hongshifen: 0,
  1669. shiJiKouFen: 0,
  1670. });
  1671. data.hutype = [];
  1672. let mgrzdgs = [0,0,0]
  1673. for (let i = 0; i < this.blZDInfo.length; ++i) {
  1674. if(this.blZDInfo[i].length > 0){
  1675. mgrzdgs[this.blZDInfo[i][0]]++
  1676. }
  1677. }
  1678. // console.warn("结算分数 炸弹信息 "+JSON.stringify(this.blZDInfo)+" mgrzdgs "+mgrzdgs);
  1679. // 计算输赢
  1680. for (let i = 0; i < wins.length; ++i) {
  1681. if (winner.chs.indexOf(i) != -1) {
  1682. wins.forEach((w, c) => {
  1683. //计算剩余牌分
  1684. let sy = 0;
  1685. if(this.handCards[c].length > 1) sy = this.handCards[c].length * this.cell;
  1686. if (c != i) {
  1687. w.win -= sy;
  1688. wins[i].win += sy;
  1689. w.cardfen -= sy;
  1690. wins[i].cardfen += sy;
  1691. }
  1692. //计算全关翻倍分
  1693. if(this.handCards[c].length == this.cardCount){
  1694. if (c != i) {
  1695. w.win -= sy;
  1696. wins[i].win += sy;
  1697. w.cardfen -= sy;
  1698. wins[i].cardfen += sy;
  1699. }
  1700. }
  1701. });
  1702. //计算扎鸟分(红桃十翻倍)
  1703. wins.forEach((w, c) => {
  1704. let sy = 0;
  1705. if (c == this.zhaniaoChair || i == this.zhaniaoChair) {
  1706. if(this.handCards[c].length > 1) sy = this.handCards[c].length * this.cell
  1707. w.win -= sy;
  1708. wins[i].win += sy;
  1709. w.hongshifen -= sy;
  1710. wins[i].hongshifen += sy;
  1711. }
  1712. //计算全关翻倍分
  1713. if(this.handCards[c].length == this.cardCount){
  1714. if (c != i) {
  1715. w.win -= sy;
  1716. wins[i].win += sy;
  1717. w.cardfen -= sy;
  1718. wins[i].cardfen += sy;
  1719. }
  1720. }
  1721. });
  1722. }
  1723. //计算炸弹分
  1724. wins.forEach((w, c) => {
  1725. let sy = 10*mgrzdgs[i];
  1726. if (c != i) {
  1727. w.win -= sy;
  1728. wins[i].win += sy;
  1729. w.zhadanfen -= sy;
  1730. wins[i].zhadanfen += sy;
  1731. }
  1732. });
  1733. // 手牌
  1734. wins[i].handCard = this.logic.deepCloneTL(this.handCards[i]);
  1735. wins[i].isZhaNiao = this.zhaniaoChair == i;
  1736. wins[i].isQuanGuan = this.handCards[i].length == this.cardCount;
  1737. }
  1738. // let str3 = "table 333结算函数---id:"+this.id +",结算模式"+mode
  1739. // logger.info(str3);////cssj
  1740. //////TL++
  1741. let shiJiKouFen = [];
  1742. if(this.playerAllCount == 2) shiJiKouFen = [wins[0].win,wins[1].win];
  1743. else if(this.playerAllCount == 3) shiJiKouFen = [wins[0].win,wins[1].win,wins[2].win];
  1744. for (let i = 0; i < this.ccount; ++i) {
  1745. wins[i].shiJiKouFen = shiJiKouFen[i];
  1746. }
  1747. //console.warn("实际扣分XXX",shiJiKouFen,wins[0].win,wins[1].win,wins[2].win,wins[3].win)
  1748. // 胜负情况
  1749. data.wins = wins;
  1750. let bjsy = [];//本局每个人的输赢
  1751. for (let i = 0; i < this.ccount; ++i) {
  1752. let zhanjiItem = {
  1753. zf: wins[i].win,
  1754. zn: wins[i].isZhaNiao,
  1755. qg: wins[i].isQuanGuan,
  1756. ps: wins[i].handCard.length,
  1757. pf: wins[i].cardfen,
  1758. zdf: wins[i].zhadanfen,
  1759. hsf: wins[i].hongshifen,
  1760. }
  1761. bjsy[i] = zhanjiItem;
  1762. }
  1763. this.sszjDataList[this.sszjDataList.length] = bjsy;
  1764. this.over += 1;// 局数+1
  1765. //ts++
  1766. let sszjScore = [];//ts++实时本局成绩
  1767. let sszjAllScore = [];//ts++实时总成绩
  1768. // 记录分数
  1769. for (let i = 0; i < this.ccount; ++i) {
  1770. let user = this.users[i];
  1771. if (user)
  1772. {
  1773. sszjScore[i] = shiJiKouFen[i];
  1774. this.score.writeScore(user.id,shiJiKouFen[i], 1);//设置分数
  1775. sszjAllScore[i] = this.score.getScore(user.id);
  1776. // if(this.gameKindTL == 2) sszjAllScore[i] -=200;
  1777. if(this.over == 1)
  1778. {
  1779. this.score.writeCost(user.id,this.cost, 0); //ts++设置消耗
  1780. }
  1781. }
  1782. }
  1783. let endmode=ENDMODE.PLAYING;
  1784. if(this.isGameOver())
  1785. {
  1786. this.isGameOk=true;
  1787. endmode=ENDMODE.NORMALEND;//局数完成--正常结束
  1788. }
  1789. data.isover = this.isGameOk;
  1790. data.nowTime = Date.now();
  1791. this.setPaijuHuiFangData(M.CONCLUDE,data);/////TL++ 牌局回放 push结算数据
  1792. /////TL++,用于记录玩家牌局回放的json文件名
  1793. this.pjhffileName[this.pjhffileName.length] = this.PJHF.getjsonFileName(this.over,this.recordid,this.ctime);
  1794. // let str4 = "table 444结算函数---id:%s"+this.id +"结算模式"+mode
  1795. // logger.info(str4);////cssj
  1796. //ts++胡的人
  1797. let hu=-1;
  1798. if (winner.chs.length >0 && winner.chs[0] >= 0 && winner.chs[0] <= 3)
  1799. {
  1800. hu=winner.chs[0];
  1801. }
  1802. //ts++实时战绩
  1803. //this.sszjs.push({_id: String(this.over),c0Score:bjsy[0],c1Score:bjsy[1], c2Score:bjsy[2], c3Score:bjsy[3],banker:this.chBanker,hu:hu,pao:winner.lead, fName:jsonFileName});
  1804. this.sszjs.push({_id: String(this.over),sszjScore:sszjScore,sszjAllScore:sszjAllScore,banker:this.chBanker,hu:hu,pao:winner.lead});
  1805. // 切换庄家
  1806. this.chBanker = winner.chs[0];
  1807. /////TL++,10月9号,为了解决冲刺时前端的玩家分数偶尔会显示负数的bug
  1808. data.playNowScore = [];
  1809. for (let i = 0; i < this.ccount; ++i) {
  1810. let user = this.users[i];
  1811. if (user)
  1812. {
  1813. data.playNowScore[i] = this.score.getScore(user.id);
  1814. }
  1815. }
  1816. // 重置本局
  1817. this.resetRound();
  1818. // 结算通知
  1819. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.CONCLUDE, data: data });
  1820. this.PJHF.writePJHFJson({"pjhfDataList":this.PaijuHuiFang},this.over,this.id)
  1821. // this.logic.isZHYZ = false; /////TL++,是否最后一张
  1822. // yield this.pushMsgAsync(-1, 'paodekuai_event', { type: 100, data: {"pjhfDataList":this.PaijuHuiFang}});//////最终发送给前端的牌局回放
  1823. // let str6 = "table end 结算函数-id:"+this.id +"结算模式"+mode
  1824. // logger.info(str6);////cssj
  1825. yield this.endResultAsync(endmode);
  1826. });
  1827. // 发送聊天
  1828. proto.sendMsgAsync = cor(function* (chairId, msg) {
  1829. // console.error("sscc发送聊天+++++++++++++++++++++++++++++++++",chairId,msg)
  1830. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.CHAT, data: { chairId: String(chairId), msg: msg } });
  1831. return { code: C.OK };
  1832. });
  1833. // 收费聊天 礼物收费
  1834. proto.vsendMsgAsync = cor(function* (schairId, dchairId, msg) {
  1835. if (schairId == dchairId || !this.users[dchairId]) {
  1836. return { code: C.FAILD, msg: C.GAME_PARAM_ERROR };
  1837. }
  1838. let user = this.users[schairId];
  1839. if (!user) {
  1840. return { code: C.FAILD, msg: C.TABLE_NOT_USER };
  1841. }
  1842. let lwcost = this.LWKF[msg.type];//////TL++礼物扣费
  1843. if(lwcost > 0){
  1844. var player = yield this.app.models.Player.findByIdAsync(user.id, 'diamond');
  1845. if(player)
  1846. {
  1847. if (((player.diamond) || 0) < lwcost) {
  1848. return { code: C.FAILD, msg: C.GAME_DIAMOND_LOW };
  1849. }
  1850. let dSource=player.diamond;
  1851. let dNow=player.diamond-lwcost;
  1852. player.diamond -= lwcost;
  1853. yield player.saveAsync();
  1854. // 钻石记录
  1855. var diamondrecord = new this.app.models.DiamondRecord({
  1856. _id: uuid.v1(),
  1857. playerId: user.id,
  1858. dType: 5,//礼物
  1859. dSource: dSource,
  1860. dSwap: -lwcost,
  1861. dNow: dNow,
  1862. tableId: this.recordid
  1863. });
  1864. yield diamondrecord.saveAsync();
  1865. //ts++设置消耗
  1866. // this.score.writeCost(user.id,0, lwcost);
  1867. }
  1868. }
  1869. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.FEE_CHAT, data: { cost: String(lwcost),schairId: String(schairId), dchairId: String(dchairId), msg: msg } });
  1870. return { code: C.OK };
  1871. });
  1872. //ts++写分 endtype = { 正常: 0,局数完成: 1, 房主解散: 2, 申请解散: 3 ,超时解散: 4 };
  1873. proto.writeResultAsync = cor(function* (endmode) {
  1874. if(this.yjxrzj){
  1875. logger.warn("出错了已经写入过战绩了-------------- " + this.yjxrzj );
  1876. return;
  1877. }
  1878. this.yjxrzj = true;
  1879. yield this.writeResultAsync2(endmode);
  1880. });
  1881. //ts++写分 endtype = { 正常: 0,局数完成: 1, 房主解散: 2, 申请解散: 3 ,超时解散: 4 };
  1882. proto.writeResultAsync2 = cor(function* (endmode) {
  1883. logger.warn("牌局写入-------------- " + this.id );
  1884. // console.warn("ts++---------牌局写入writeResultAsync",this.id);
  1885. let gameCost=0;//游戏消耗
  1886. let giftCost = 0;////道具消耗
  1887. this.etime = Date.now();
  1888. let users = [];
  1889. let localUsers = [];
  1890. var scorers = this.score.getUsers();
  1891. if (scorers.length > 0)
  1892. {
  1893. var scorersSort = _.sortBy(scorers, (i) => i.chairId);
  1894. for (let scorer of scorersSort) {
  1895. gameCost+=this.cost;
  1896. giftCost+=scorer.giftCost;
  1897. let userscore=scorer.score;
  1898. // if(this.gameKindTL == 2) userscore -= 200;
  1899. users.push({_id: scorer.playerId,chairId:scorer.chairId,userId: scorer.userId, name: scorer.name, sex: scorer.sex, headurl: scorer.headurl,over: scorer.over, score: userscore});
  1900. //, gameCost: scorer.gameCost,giftCost: scorer.giftCost,diamond: scorer.diamond
  1901. localUsers.push({_id: scorer.playerId,userId: scorer.userId, name: scorer.name, gameCost: scorer.gameCost,giftCost: scorer.giftCost,});
  1902. }
  1903. }
  1904. // if(this.isGameOk)////以前是解散的不算返利
  1905. if(this.over > 0)////改成只要玩家扣钻了就有返利
  1906. {
  1907. // this.agentRebate=gameCost;//parseInt(gameCost*0.5);
  1908. this.agentRebate=gameCost+giftCost;////礼物也算消耗进行返利
  1909. // console.warn("代理返利+++++",this.agentRebate);
  1910. }
  1911. else
  1912. {
  1913. this.agentRebate=0;
  1914. }
  1915. //console.warn("实时战绩",this.sszjs);//ts++
  1916. this.PJHF.getTSjsonFileName(100,this.recordid,this.ctime);/////TL++,用于记录玩家牌局回放的json文件名
  1917. // console.error("000HHHHHHHHHHHHHHHHHHHHHH",this.pjhffileName.length,this.pjhffileName);
  1918. let datats = {
  1919. _id: this.recordid,//记录
  1920. gameId: this.gameId,
  1921. tableNo: this.id,
  1922. ownerId: this.ownerId,
  1923. agentId: this.agentId,
  1924. type: this.type,
  1925. kind: this.gameKindTL,//玩法 2冲刺
  1926. other: this.other,//////TL++2人3人的游戏规则
  1927. playerCount: this.playerAllCount,//游戏人数
  1928. round: this.round,//
  1929. over: this.over,//游戏局数
  1930. ctime: this.ctime,//创建时间
  1931. stime: this.stime,//开始时间
  1932. time: this.etime,//结束时间
  1933. endMode: endmode,//结束类型
  1934. gameCost: gameCost,//游戏消耗
  1935. giftCost: giftCost,//礼物消耗
  1936. agentRebate: parseInt(this.agentRebate),//代理返利
  1937. sszjFile: this.logic.deepCloneTL(this.pjhffileName),
  1938. sszj: this.logic.deepCloneTL(this.sszjs),
  1939. users: users
  1940. }
  1941. this.PJHF.writeTSJson(datats,100,this.id);////在开始第一局的时候将桌子信息写入本地的json文件
  1942. var fhmjtable = new this.app.models.FHMJTables({
  1943. _id: this.recordid,//记录
  1944. gameId: this.gameId,
  1945. tableNo: this.id,
  1946. ownerId: this.ownerId,
  1947. agentId: this.agentId,
  1948. type: this.type,
  1949. kind: this.gameKindTL,//玩法 2冲刺
  1950. other: this.other,//////TL++2人3人的游戏规则
  1951. playerCount: this.playerAllCount,//游戏人数
  1952. round: this.round,//
  1953. over: this.over,//游戏局数
  1954. ctime: this.ctime,//创建时间
  1955. stime: this.stime,//开始时间
  1956. time: this.etime,//结束时间
  1957. endMode: endmode,//结束类型
  1958. gameCost: gameCost,//游戏消耗
  1959. giftCost: giftCost,//礼物消耗
  1960. agentRebate: parseInt(this.agentRebate),//代理返利
  1961. sszjFile: this.pjhffileName,
  1962. sszj: this.sszjs,
  1963. users: users
  1964. });
  1965. logger.warn("fhmjtable new--------111 " + this.recordid );
  1966. // console.warn("fhmjtable new",fhmjtable);
  1967. yield fhmjtable.saveAsync();
  1968. //下面是记录返利相关的
  1969. if(this.agentId && this.agentRebate>0){
  1970. yield this.lsetReabte.writeReabteInfo(this.agentId,this.etime,this.agentRebate,gameCost,giftCost,this.recordid,localUsers,this.gameId);
  1971. // yield this.lsetReabte.writePlayerCountInfo(this.agentId,this.etime,users,this.cost,this.isGameOk,this.gameId);
  1972. }
  1973. //下面是记录邀请新人按比例送钻这个活动的数据
  1974. if(!this.lconfigCommon) {
  1975. // console.warn("邀请新人送钻石活动 this.lconfigCommon 不存在 "+this.etime);
  1976. this.lconfigCommon = new configCommon(this.app);
  1977. }
  1978. yield this.lconfigCommon.yxActivityAsync(scorers,this.etime);
  1979. logger.warn("战绩写入结束--",this.id);
  1980. // return { code: C.OK };
  1981. });
  1982. // 结束信息 var endtype = { 局数完成: 1, 主动解散: 2, 断线解散: 3 ,超时解散: 4 };
  1983. proto.endResultAsync = cor(function* (endmode) {
  1984. // console.warn("ts++---------记录信息",this.id);
  1985. let str6 = "table 结束信息--id: "+this.id +" ,结算模式 "+endmode;
  1986. logger.warn(str6);////cssj
  1987. if(endmode>ENDMODE.PLAYING)//ts++关闭
  1988. {
  1989. let nowTime = Date.now();
  1990. if(this.state<STATE.END)//ts++防止重复写入
  1991. {
  1992. this.state = STATE.END;
  1993. if (this.endTimer) {
  1994. clearTimeout(this.endTimer);
  1995. this.endTimer = null;
  1996. }
  1997. if (this.overTimer) {
  1998. clearTimeout(this.overTimer);
  1999. this.overTimer = null;
  2000. }
  2001. // console.warn("ts++---------局数完成",this.over);
  2002. if(this.over>0)
  2003. {
  2004. var scorers = this.score.getUsers();
  2005. if (scorers.length > 0) {
  2006. let data = {
  2007. _id: this.recordid,
  2008. gameId: this.gameId,
  2009. tableNo: this.id,
  2010. ownerId: this.ownerId,
  2011. type:String(this.type),
  2012. kind: String(this.gameKindTL),
  2013. over: String(this.over),
  2014. round: String(this.round),
  2015. time: String(nowTime),
  2016. ctime: String(this.ctime),
  2017. keep: String(nowTime - this.stime),
  2018. other: this.other,
  2019. playerCount:this.playerAllCount,
  2020. agentId: this.agentId
  2021. };
  2022. let collects = [];
  2023. for (let scorer of scorers) {
  2024. let userscore=scorer.score;
  2025. // if(this.gameKindTL == 2) userscore -= 200;//TL++,因为总的结算界面的每个玩家的分数范围为-200 ~ 600
  2026. collects.push({ chairId:scorer.chairId,name: scorer.name, sex: scorer.sex, headurl: scorer.headurl, score: userscore });
  2027. }
  2028. data.users = _.sortBy(collects, (i) => -i.score);
  2029. //data.sszjFile=this.pjhffileName;
  2030. data.sszj=this.sszjs;
  2031. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.TOTAL_CONCLUDE, data: data });////汇总结算
  2032. }
  2033. //console.warn("ts++---------牌局写入");
  2034. yield this.writeResultAsync(endmode);
  2035. }
  2036. //console.warn("ts---------牌局结束");
  2037. for (let user of this.users) {
  2038. if (user) {
  2039. if (user.isOffline())
  2040. {
  2041. user.state = User.STATE.FREE;
  2042. user.state2 = User.STATE.FREE;
  2043. this.leaveUsers.push(user.id);
  2044. ///yield this.game.leaveTableAsync(user.id);
  2045. }
  2046. else
  2047. {
  2048. user.state = User.STATE.FREE;
  2049. user.state2 = User.STATE.FREE;
  2050. }
  2051. }
  2052. }
  2053. }
  2054. if(endmode==ENDMODE.SYSTEMEND)
  2055. {
  2056. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.TABLE_JIESAN });
  2057. }
  2058. // console.warn("调用离开 length ",this.leaveUsers.length+" this.leaveUsers "+JSON.stringify(this.leaveUsers));
  2059. // console.warn("调用离开 BSlength ",this.leaveUsersBS.length+" this.leaveUsersBS "+JSON.stringify(this.leaveUsersBS));
  2060. for (var i = 0; i < this.leaveUsersBS.length; i++) {
  2061. let itemUid = this.leaveUsersBS[i];
  2062. if(this.leaveUsers.indexOf(itemUid) == -1) {
  2063. this.leaveUsers.push(itemUid);
  2064. // console.warn("this.leaveUsers 增加 leaveUsersBS 元素 "+itemUid + " " +JSON.stringify(this.leaveUsers));
  2065. }
  2066. }
  2067. if(this.leaveUsers.length>0)
  2068. {
  2069. this.app.timer.setTimeout(() => this.leaveUserTimeAsync(), 100);
  2070. }
  2071. // var gametable = yield this.app.models.GameTable.findByIdAsync(this.recordid, '_id tableNo agentId endMode');
  2072. // if(gametable){
  2073. // gametable.endMode = 1;
  2074. // yield gametable.saveAsync();
  2075. // }
  2076. this.game.deleteTable(this.id);//ts++删除房间
  2077. // let str5 = "table 结束信息22 关闭-id:"+this.id +"结算模式"+endmode;
  2078. // logger.info(str5);////cssj
  2079. }
  2080. else//普通结束
  2081. {
  2082. // let str5 = "table 结束信息 普通结束---id:"+this.id +"结算模式"+endmode
  2083. // logger.info(str5);////cssj
  2084. if(this.lsetReabte.getIsBS(this.agentId,this.ownerName,this.ownerUid)){
  2085. for (let user of this.users) {
  2086. if(user.state2 == User.STATE.OFFLINE && this.leaveUsersBS.indexOf(user.id) == -1) {
  2087. this.leaveUsersBS.push(user.id);
  2088. }
  2089. }
  2090. }
  2091. this.state = STATE.FREE2;
  2092. for (let user of this.users) {
  2093. if (user) user.state2 = User.STATE.FREE;
  2094. }
  2095. if(this.lsetReabte.getIsBS(this.agentId,this.ownerName,this.ownerUid)){
  2096. if(this.everyIsAutoOut.indexOf(1) != -1){
  2097. this.autoReadyTimer = this.app.timer.setTimeout(() => this.autoReadyOnBisai(), 5000);//这个延迟时间不能太短
  2098. }
  2099. if(this.everyIsAutoOut.indexOf(0) != -1){
  2100. this.autoReadyTimer2 = this.app.timer.setTimeout(() => this.autoReadyOnBisai2(), 9000);
  2101. }
  2102. }
  2103. }
  2104. let str7 = "table end 结束信息---id:%s "+this.id +" 结算模式 "+endmode;
  2105. logger.warn(str7);////cssj
  2106. });
  2107. //比赛房间的话,玩家处于托管状态的时候2秒之后自动准备 因为定时器里不能yield,所以改成这种方式
  2108. proto.autoReadyOnBisai = cor(function* (users) {
  2109. if(this.autoReadyTimer)
  2110. {
  2111. clearTimeout(this.autoReadyTimer);
  2112. this.autoReadyTimer = null;
  2113. }
  2114. for (let user of this.users) {
  2115. // console.warn("玩家处于托管状态的时候2秒之后自动准备--- user.state "+user.state+" user.state2 "+user.state2);
  2116. if(this.everyIsAutoOut[user.chairId] == 1){
  2117. if(user.state2 == User.STATE.FREE || user.state2 == User.STATE.OFFLINE){
  2118. yield this.game.readyGameAsync(user.id);
  2119. }
  2120. }
  2121. }
  2122. });
  2123. //比赛房间的话,玩家不处于托管状态的时候12秒之后自动准备 因为定时器里不能yield,所以改成这种方式
  2124. proto.autoReadyOnBisai2 = cor(function* (users) {
  2125. if(this.autoReadyTimer2)
  2126. {
  2127. clearTimeout(this.autoReadyTimer2);
  2128. this.autoReadyTimer2 = null;
  2129. }
  2130. for (let user of this.users) {
  2131. // console.warn("玩家不处于托管状态的时候12秒之后自动准备--- user.state "+user.state+" user.state2 "+user.state2);
  2132. if(this.everyIsAutoOut[user.chairId] == 0){
  2133. if(user.state2 == User.STATE.FREE || user.state2 == User.STATE.OFFLINE){
  2134. this.everyIsAutoOut[user.chairId] = 1;
  2135. yield this.game.readyGameAsync(user.id);
  2136. }
  2137. }
  2138. }
  2139. });
  2140. //ts++离开用户退出定时器
  2141. proto.leaveUserTimeAsync = cor(function* () {
  2142. // console.warn("离开用户退出定时器,离开用户数==%d",this.leaveUsers.length);////cssj
  2143. if(this.leaveUsers.length>0)
  2144. {
  2145. let userid = this.leaveUsers[0];
  2146. this.leaveUsers.splice(0, 1);
  2147. let str7 = "table end 离开用户退出定时器---id:%s "+this.id +" userid "+userid;
  2148. logger.warn(str7);////cssj
  2149. yield this.game.leaveTableAsync(userid);
  2150. }
  2151. if(this.leaveUsers.length>0)
  2152. {
  2153. this.app.timer.setTimeout(() => this.leaveUserTimeAsync(), 100);
  2154. }
  2155. });
  2156. // TL++,得到玩家位置
  2157. proto.sendLocationAsync = cor(function* (user,msg) {
  2158. /////设置玩家的经纬度
  2159. user.longitude = msg.longitude; // 经度,浮点数,范围为180 ~ -180。
  2160. user.latitude = msg.latitude; // 纬度,浮点数,范围为90 ~ -90
  2161. let tempData = {
  2162. userId: user.userId,
  2163. account: user.account,
  2164. longitude: msg.longitude,
  2165. latitude: msg.latitude
  2166. }
  2167. //////向其他玩家广播该玩家位置
  2168. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.COAST_PLAYERLOCATION, data: tempData });
  2169. return { code: C.OK, data: tempData };
  2170. });
  2171. // 玩家信息
  2172. proto.roleInfoAsync = cor(function* (chairId) {
  2173. // console.log("玩家信息玩家信息玩家信息");
  2174. var user = this.users[chairId];
  2175. if (!user) {
  2176. return { code: C.FAILD, msg: C.GAME_PARAM_ERROR };
  2177. }
  2178. var data = { userId: '0', ttCount: '0', winCount: '0', noCount: '0', runCount: '0' };
  2179. data.userId =user.userId;
  2180. return { code: C.OK, data: data };
  2181. });
  2182. //ts++请求结束定时器
  2183. proto.overTimeAsync = cor(function* (endmode) {
  2184. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.TABLE_JIESAN });
  2185. let str6 = "table 请求结束定时器---id: "+this.id +" ,endmode: "+endmode
  2186. logger.warn(str6);////cssj
  2187. if(this.autoOutTimer)
  2188. {
  2189. clearTimeout(this.autoOutTimer);
  2190. this.autoOutTimer = null;
  2191. }
  2192. if(this.autoReadyTimer)
  2193. {
  2194. clearTimeout(this.autoReadyTimer);
  2195. this.autoReadyTimer = null;
  2196. }
  2197. if(this.autoReadyTimer2)
  2198. {
  2199. clearTimeout(this.autoReadyTimer2);
  2200. this.autoReadyTimer2 = null;
  2201. }
  2202. yield this.endResultAsync(endmode);//ts++ 房主解散 写分
  2203. });
  2204. // 请求结束
  2205. proto.overTableAsync = cor(function* (user) {
  2206. // console.warn("ts+++++请求结束",user.chairId);
  2207. let str3 = "table 请求结束.......id: "+ this.id + " user.chairId: " + user.chairId + " user.name: " + user.name ;
  2208. logger.warn(str3);////cssj
  2209. if(this.state == STATE.END)
  2210. {
  2211. this.leaveAsync(user);
  2212. return { code: C.OK, data:{jieSanType: 2}};//离开房间
  2213. }
  2214. if(this.reqJieSan.indexOf(2) != -1) return;/////有发起人的时候
  2215. // console.warn("2222请求结束请求结束请求结束",this.reqJieSan);
  2216. //解散桌子数据,前面为chirid后面为情况-1:未操作 0:拒绝 1:同意 2为解散发起
  2217. //jieSanType =1:游戏开始前房主申请解散 =2:游戏开始前非房主玩家退出房间 =3:游戏过程中玩家申请解散 =4游戏过程中是房主但没参与游戏退出房间 =5其他
  2218. if(this.gameNeverStart) {//游戏是否从未开始过,用于解散房间判断
  2219. if(user.userId == this.ownerUid){
  2220. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.TABLE_JIESAN });
  2221. // let str5 = "table 房主解散-id:"+this.id+ ",uid"+user.userId;
  2222. // logger.info(str5);////cssj
  2223. yield this.endResultAsync(ENDMODE.OWNEREND);//ts++ 房主解散 写分
  2224. return { code: C.OK, data:{jieSanType: 1}};
  2225. }
  2226. else{
  2227. this.leaveAsync(user);
  2228. return { code: C.OK, data:{jieSanType: 2}};//离开房间
  2229. }
  2230. }
  2231. else
  2232. {
  2233. let chairId=user.chairId;
  2234. if(chairId >= 0 && chairId < 4 )
  2235. {
  2236. if(this.overFlag==0)//发起
  2237. {
  2238. this.overFlag = 1;
  2239. this.reqJieSan[0]=-1;
  2240. this.reqJieSan[1]=-1;
  2241. this.reqJieSan[2]=-1;
  2242. this.reqJieSan[3]=-1;
  2243. this.reqJieSan[chairId]=2;
  2244. let jsdata = [];//ts++实时本局成绩
  2245. jsdata[0] = this.reqJieSan[0];
  2246. jsdata[1] = this.reqJieSan[1];
  2247. jsdata[2] = this.reqJieSan[2];
  2248. jsdata[3] = this.reqJieSan[3];
  2249. this.JSFJTime = 60;//////解散倒计时60秒
  2250. this.SQJSTime = Date.now() + this.JSFJTime*1000;
  2251. if (!this.overTimer) this.overTimer = this.app.timer.setTimeout(() => this.overTimeAsync(ENDMODE.REGEND),this.JSFJTime*1000);//解散倒计时60秒
  2252. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.REQUEST_END, data: { chairId: String(chairId),time: this.JSFJTime,jsdata:jsdata}});
  2253. return { code: C.OK, data:{jieSanType: 3}};
  2254. }
  2255. else//同意
  2256. {
  2257. return this.agreeOverAsync(chairId);
  2258. }
  2259. }
  2260. else
  2261. {
  2262. return { code: C.FAILD, msg: C.TABLE_ALREADY_SQJS };
  2263. }
  2264. }
  2265. return { code: C.OK, data:{jieSanType: 5}};
  2266. });
  2267. // 拒绝结束
  2268. proto.refuseOverAsync = cor(function* (user) {
  2269. let str3 = "table 拒绝结束.......id: "+ this.id + " user.chairId: " + user.chairId + " user.name: " + user.name ;
  2270. logger.warn(str3);////cssj
  2271. if(this.state == STATE.END)
  2272. {
  2273. this.leaveAsync(user);
  2274. return { code: C.OK, data:{jieSanType: 2}};//离开房间
  2275. }
  2276. if(this.overFlag == 0) //ts++已经拒绝了
  2277. {
  2278. return { code: C.OK };
  2279. }
  2280. this.overFlag = 0;
  2281. let chairId=user.chairId;
  2282. // console.error("ts++----------拒绝结束",chairId);
  2283. this.reqJieSan[chairId]=0;//解散桌子数据,前面为chirid后面为情况-1:未操作 0:拒绝 1:同意 2为解散发起
  2284. let jsdata = [];//ts++实时本局成绩
  2285. jsdata[0] = this.reqJieSan[0];
  2286. jsdata[1] = this.reqJieSan[1];
  2287. jsdata[2] = this.reqJieSan[2];
  2288. jsdata[3] = this.reqJieSan[3];
  2289. if (this.overTimer) {
  2290. clearTimeout(this.overTimer);
  2291. this.overTimer = null;
  2292. }
  2293. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.REFUSE_END, data: { chairId: String(chairId),time: 0,jsdata:jsdata} });
  2294. //this.reqJieSan = [[-1,-1],[-1,-1],[-1,-1],[-1,-1]];/////解散桌子数据,前面为chirid后面为情况-1:未操作 0:拒绝 1:同意 2为解散发起
  2295. this.reqJieSan[0]=-1;
  2296. this.reqJieSan[1]=-1;
  2297. this.reqJieSan[2]=-1;
  2298. this.reqJieSan[3]=-1;
  2299. return { code: C.OK };
  2300. });
  2301. // 同意结束
  2302. proto.agreeOverAsync = cor(function* (user) {
  2303. let str3 = "table 同意结束.......id: "+ this.id + " user.chairId: " + user.chairId + " user.name: " + user.name ;
  2304. logger.warn(str3);////cssj
  2305. if(this.state == STATE.END)
  2306. {
  2307. this.leaveAsync(user);
  2308. return { code: C.OK, data:{jieSanType: 2}};//离开房间
  2309. }
  2310. if(this.overFlag == 0) //ts++已经拒绝了
  2311. {
  2312. return { code: C.OK };
  2313. }
  2314. let chairId=user.chairId;
  2315. // console.error("ts++----------同意结束",chairId);
  2316. this.reqJieSan[chairId] = 1;/////解散桌子数据,前面为chirid后面为情况-1:未操作 0:拒绝 1:同意 2为解散发起
  2317. let jsdata = [];//ts++实时本局成绩
  2318. jsdata[0] = this.reqJieSan[0];
  2319. jsdata[1] = this.reqJieSan[1];
  2320. jsdata[2] = this.reqJieSan[2];
  2321. jsdata[3] = this.reqJieSan[3];
  2322. this.JSFJTime = Math.floor((this.SQJSTime - Date.now())/1000);
  2323. if(this.JSFJTime >= 25)this.JSFJTime -= 20;//////解散房间倒计时60秒
  2324. else this.JSFJTime = 10;
  2325. this.SQJSTime = Date.now() + this.JSFJTime*1000;
  2326. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.AGREE_END, data: { chairId: String(chairId),time: this.JSFJTime,jsdata:jsdata} });
  2327. let jsFlag = 0;
  2328. for (let i = 0; i < 4; ++i)
  2329. {
  2330. if(this.reqJieSan[i] >=1 )
  2331. {
  2332. jsFlag+=1;
  2333. }
  2334. }
  2335. if(jsFlag>=this.ccount || this.JSFJTime<=0)
  2336. {
  2337. if(this.backStartTimer)
  2338. {
  2339. clearTimeout(this.backStartTimer);
  2340. this.backStartTimer = null;
  2341. }
  2342. if(this.autoOutTimer)
  2343. {
  2344. clearTimeout(this.autoOutTimer);
  2345. this.autoOutTimer = null;
  2346. }
  2347. if(this.autoReadyTimer)
  2348. {
  2349. clearTimeout(this.autoReadyTimer);
  2350. this.autoReadyTimer = null;
  2351. }
  2352. if(this.autoReadyTimer2)
  2353. {
  2354. clearTimeout(this.autoReadyTimer2);
  2355. this.autoReadyTimer2 = null;
  2356. }
  2357. yield this.pushMsgAsync(-1, 'paodekuai_event', { type: M.TABLE_JIESAN });
  2358. // let str4 = "table 全部同意结束-id:%s"+this.id + ",uid"+user.userId+",state"+ this.state;
  2359. // logger.info(str4);////cssj
  2360. yield this.endResultAsync(ENDMODE.REGEND);//ts++ 结束
  2361. }
  2362. else
  2363. {
  2364. if (this.overTimer) {
  2365. clearTimeout(this.overTimer);
  2366. this.overTimer = null;
  2367. }
  2368. if (!this.overTimer) this.overTimer = this.app.timer.setTimeout(() => this.overTimeAsync(ENDMODE.REGEND),this.JSFJTime*1000);//解散倒计时60秒
  2369. }
  2370. // let str3 = "table end 同意结束-id:"+this.id + ",uid"+user.userId+",state"+ this.state;
  2371. // logger.info(str3);////cssj
  2372. return { code: C.OK, data: { chairId: String(chairId),time: this.JSFJTime, jieSanType: 1 }};
  2373. });
  2374. //////TL++,设置记录游戏过程中的记录数据
  2375. proto.setPaijuHuiFangData = function (_operateKind,_data){
  2376. let data = this.logic.deepCloneTL(_data);
  2377. data.operateKind = _operateKind;
  2378. this.PaijuHuiFang[this.PaijuHuiFang.length] = data;
  2379. };
  2380. // 得到玩家位置
  2381. proto.getLocationAsync = cor(function* () {
  2382. let location = [];
  2383. // 桌上玩家
  2384. for (let i = 0; i < this.users.length; ++i) {
  2385. let user = this.users[i];
  2386. if (user) {
  2387. location.push({
  2388. chairId: user.chairId,
  2389. longitude: user.longitude,
  2390. latitude: user.latitude,
  2391. headurl: user.headurl,
  2392. name: user.name
  2393. });
  2394. }
  2395. }
  2396. // console.warn("ts+++++玩家位置",location);
  2397. return { code: C.OK, data: location };
  2398. });