package gamelogic import ( "bet24.com/servers/common" "bet24.com/servers/games/fish/bullet" _ "bet24.com/servers/games/fish/config" "bet24.com/servers/games/fish/fish" "bet24.com/servers/games/fish/fishcommon" item "bet24.com/servers/micros/item_inventory/proto" "bet24.com/servers/user" "bet24.com/utils" "encoding/json" "fmt" "math/rand" ) func (ts *tablesink) OnGameMessage(userIndex int32, cmd, data string) bool { usr := ts.table.GetPlayer(userIndex) if usr == nil { ts.table.LogWithTableId("tablesink.OnGameMessage,usr[%d] not exist", userIndex) return false } chairId := usr.GetUserChairId() if !fishcommon.IsValidChair(chairId) { ts.table.LogWithTableId("tablesink.OnGameMessage invalid chair %d", chairId) return false } defer utils.TimeCost(fmt.Sprintf("tablesink.OnGameMessage[%s]", cmd))() switch cmd { case fishcommon.ADD_BULLET: ts.addBullet(usr, cmd, data, chairId) case fishcommon.CATCH_FISH: ts.catchFish(usr, cmd, data, chairId) case fishcommon.SET_BULLET: ts.setBullet(usr, cmd, data) case fishcommon.SET_CANNON: ts.setCannon(usr, cmd, data) case fishcommon.USE_ITEM: ts.useItem(usr, cmd, data) case fishcommon.GAME_SCENE: //ts.table.NotifySceneChanged(chairId) gameScene := ts.getChairScene() ts.table.SendGameData(userIndex, fishcommon.GAME_SCENE, gameScene) // 如果鱼群来了 if ts.groupState { ts.sendGroup(userIndex, false) } case fishcommon.SPECIAL_CATCH: ts.specialCatch(usr, cmd, data) case fishcommon.SPECIAL_CATCH_END: ts.specialCatchEnd(usr, cmd, data) case fishcommon.SPECIAL_SHOOT: ts.specialShoot(usr, cmd, data) case fishcommon.UPGRADE_BULLET: ts.upgradeBullet(usr, cmd, data) default: ts.table.LogWithTableId("tablesink.HandleCmd usr(%d),unhandled cmd(%v:%v) ", usr.GetUserId(), cmd, data) return false } return false } func (ts *tablesink) addBullet(usr *user.UserInfo, cmd, data string, chairID int) { var add fishcommon.AddBullet err := json.Unmarshal([]byte(data), &add) if err != nil { ts.table.LogWithTableId("tablesink.addBullet failed %v", data) return } blt := bullet.GetBullet(add.BulletID) if blt == nil { ts.table.LogWithTableId("tablesink.addBullet invalid bulletID %d", add.BulletID) return } // 检查金币是否足够 //if !usr.ModifyGold(-bullet.Odds) { if !ts.checkGold(usr, blt.Odds, chairID) { ts.table.LogWithTableId("tablesink.addBullet not enough gold") ts.sendBulletFailed(usr, add.ClientID, "not enough gold", add.BulletID) return } b := ts.bulletmgr.addBullet(usr.GetUserId(), add.BulletID, add.Angle, add.FishKey, chairID, blt.Odds) b.ClientID = add.ClientID ts.broadcastBullet(b) } func (ts *tablesink) checkGold(usr *user.UserInfo, bulletOdds int, chairID int) bool { // 总金币 gold := usr.GetUserGold() flyingBullet := 0 //ts.bulletmgr.getFlyingBullet(usr.GetUserId()) if flyingBullet+bulletOdds > gold { ts.table.LogWithTableId("tablesink.checkGold flyingBullet(%d) + bulletOdds(%d) > gold(%d)", flyingBullet, bulletOdds, gold) return false } return true } func (ts *tablesink) sendBulletFailed(usr *user.UserInfo, clientID int, msg string, bulledID int) { data := fmt.Sprintf(`{"ClientID":%d,"Msg":"%v","BulletID":%d}`, clientID, msg, bulledID) ts.table.SendGameData(usr.GetUserIndex(), fishcommon.BULLET_FAILED, data) } func (ts *tablesink) sendBullet(userIndex int32, bullet *bullet.Bullet) { msg := fishcommon.ADD_BULLET data, _ := json.Marshal(bullet) msgData := string(data) ts.table.SendGameData(userIndex, msg, msgData) } func (ts *tablesink) broadcastBullet(bullet *bullet.Bullet) { ts.sendBullet(-1, bullet) } func (ts *tablesink) broadcastData(msg, data string) { ts.table.SendGameData(-1, msg, data) } func (ts *tablesink) sendFish(userIndex int32, fish *fish.Fish) { msg := fishcommon.ADD_FISH data, _ := json.Marshal(fish) ts.table.SendGameData(userIndex, msg, string(data)) } func (ts *tablesink) broadcastFish(fish *fish.Fish) { ts.sendFish(-1, fish) } func (ts *tablesink) getRoomUser(userId int) *fishuser { for _, v := range ts.Users { if v == nil { continue } if v.userId == userId { return v } } return nil } func (ts *tablesink) onCatchFish(fi *fish.FishInfo, earn int, userName string) { if fi.BonusFish == 0 { return } if earn <= 0 { return } //msg := fmt.Sprintf("[%s]在[%s]捕获了[%s],获得了金币[%d]", userName, config.Room.RoomDesc, fi.Name, earn) //coreservice.SendBroadcast(-1, fishcommon.GAMEID, 0, msg, "") } func (ts *tablesink) catchFish(usr *user.UserInfo, cmd, data string, chairID int) { var catch fishcommon.CatchFish fishUser := ts.getRoomUser(usr.GetUserId()) if fishUser == nil { ts.table.LogWithTableId("tablesink.catchFish failed fishUser[%d,%d] not found", usr.GetUserId(), chairID) return } err := json.Unmarshal([]byte(data), &catch) if err != nil { ts.table.LogWithTableId("tablesink.catchFish failed %v", data) return } // 查询下bullet和fish bullet := ts.bulletmgr.getBullet(catch.BulletKey) if bullet == nil || bullet.UserID != usr.GetUserId() { ts.table.LogWithTableId("tablesink.catchFish failed bullet not found") ts.sendCatchFailed(usr, catch, 0, false) return } f := ts.fishmgr.getFish(catch.FishKey) if f == nil || f.IsDead() { ts.table.LogWithTableId("tablesink.catchFish failed fish not found or dead %d", catch.FishKey) //ts.fishmgr.dump() ts.sendCatchFailed(usr, catch, bullet.BulletID, false) return } fi := fish.GetFishInfo(f.FishID) if fi == nil { ts.table.LogWithTableId("catshFish fishID[%d] invalid", f.FishID) return } ok := ts.writeUserGold(usr, fishUser, -bullet.GetOdds()) if !ok { ts.table.LogWithTableId("tablesink.catchFish failed insufficient balance") //ts.fishmgr.dump() ts.sendCatchFailed(usr, catch, bullet.BulletID, false) return } fishUser.setWaterPoolValue(-bullet.GetOdds(), bullet.GetOdds()) // 添加奖池 if ts.prizePool != nil { ts.sendPoolValue() } var ret fishcommon.CatchFishRet ret.CatchFish = catch ret.BulletID = bullet.BulletID ret.UserId = usr.GetUserId() ret.IsCatch = f.IsCatch(fishUser.getUserOdds(), ts.systemOdds, ts.roomInfo.OddsExtra) if ret.IsCatch { f.Status = fish.Fish_Dead ret.Coin = bullet.GetOdds() * f.GetOdds() ts.onCatchFish(fi, ret.Coin, usr.GetUserNickName()) // 是否产生道具 ret.ItemId, ret.ItemCount = ts.fishDrop.getDropItem(f.FishID) if ret.ItemCount > 0 { var items []item.ItemPack items = append(items, item.ItemPack{ItemId: ret.ItemId, Count: ret.ItemCount}) item.AddItems(usr.GetUserId(), items, "捕鱼掉落", common.LOGTYPE_FISH_DROP) } // 转盘鱼 ret.PrizeWheelItemId, ret.PrizeWheelItemCount = f.GetPrize() if ret.PrizeWheelItemCount > 0 { var items []item.ItemPack items = append(items, item.ItemPack{ItemId: ret.PrizeWheelItemId, Count: ret.PrizeWheelItemCount}) item.AddItems(usr.GetUserId(), items, "捕鱼转盘", common.LOGTYPE_FISH_DROP) } if fi.SpecialType > 0 { ts.table.LogWithTableId("catchFish 击中特效鱼 %v", fi) // 如果是slot if fi.SpecialEffect == item.SpecialEffect_Slot { ret.SlotMultiple = fi.Param1 + rand.Intn(fi.Param2-fi.Param1) ret.Coin += bullet.GetOdds() * ret.SlotMultiple ts.table.LogWithTableId("catchFish 击中Slot鱼 产生倍数 %d", ret.SlotMultiple) } else { ts.Users[chairID].addSpecial(f.FishKey, bullet.GetOdds(), fi.SpecialEffect, fi.SpecialType, fi.Param1, fi.Param2) } } else { ts.table.LogWithTableId("catchFish 击中普通鱼 %v", fi) } ts.broadcastCatch(ret, false) // 是否产生奖池 if ts.prizePool != nil && fi.BonusFish > 0 { var draw fishcommon.PrizePoolDraw_resp draw.UserId = usr.GetUserId() draw.Bingo, draw.Point, draw.Pool = ts.prizePool.Draw(ret.UserId, bullet.GetOdds()) if draw.Bingo { // 写分 ts.writeUserGold(usr, fishUser, draw.Point) fishUser.setWaterPoolValue(draw.Point, 0) } ts.broadcastPoolDraw(draw) ts.sendPoolEnergy(ret.UserId) } } else { ts.sendCatch(usr.GetUserIndex(), ret, false) } // ts.table.LogWithTableId("catchFish UserID[%d],BulletOdds[%d],Win[%d],FishID[%d]", ret.UserId, bullet.GetOdds(), ret.Coin, catch.FishKey) // 写分 ts.writeUserGold(usr, fishUser, ret.Coin) fishUser.setWaterPoolValue(ret.Coin, 0) // 加入纪录 ts.recordmgr.addUserRecord(ret.UserId, f.FishID, bullet.GetOdds(), ret.Coin) // 删除子弹 ts.bulletmgr.removeBullet(catch.BulletKey) } func (ts *tablesink) sendConfig(userIndex int32) { ts.table.SendGameData(userIndex, fishcommon.CONFIG_BULLET, bullet.GetConfig()) ts.table.SendGameData(userIndex, fishcommon.CONFIG_FISH, fish.GetFishConfig()) } func (ts *tablesink) broadcastCatch(catch fishcommon.CatchFishRet, isSpecial bool) { ts.sendCatch(-1, catch, isSpecial) } func (ts *tablesink) sendCatch(userIndex int32, catch fishcommon.CatchFishRet, isSpecial bool) { msg := fishcommon.CATCH_FISH if isSpecial { msg = fishcommon.SPECIAL_CATCH } data, _ := json.Marshal(catch) msgData := string(data) ts.table.SendGameData(userIndex, msg, msgData) } func (ts *tablesink) sendCatchFailed(usr *user.UserInfo, catch fishcommon.CatchFish, bulletID int, isSpecial bool) { msg := fishcommon.CATCH_FAILED if isSpecial { msg = fishcommon.SPECIAL_CATCH } var f fishcommon.CatchFishFailed f.CatchFish = catch f.BulletID = bulletID data, _ := json.Marshal(f) msgData := string(data) ts.table.SendGameData(usr.GetUserIndex(), msg, msgData) } func (ts *tablesink) setBullet(usr *user.UserInfo, cmd, data string) { var bulletID fishcommon.SetBullet err := json.Unmarshal([]byte(data), &bulletID) if err != nil { ts.table.LogWithTableId("tablesink.setBullet failed %v", data) return } fishUser := ts.getRoomUser(usr.GetUserId()) if fishUser == nil { return } if fishUser.setBullet(bulletID.BulletID) { // 广播玩家信息 ts.broadCastUserInfo(usr) } } func (ts *tablesink) setCannon(usr *user.UserInfo, cmd, data string) { var cannon fishcommon.SetCannon err := json.Unmarshal([]byte(data), &cannon) if err != nil { ts.table.LogWithTableId("tablesink.setCannon failed %v", data) return } fishUser := ts.getRoomUser(usr.GetUserId()) if fishUser == nil { return } if fishUser.setCannon(cannon.Cannon, true) { // 广播玩家信息 ts.broadCastUserInfo(usr) } else { ts.table.SendGameData(usr.GetUserIndex(), cmd, "setCannon failed") } } func (ts *tablesink) useItem(usr *user.UserInfo, cmd, data string) { var itm fishcommon.UseItem err := json.Unmarshal([]byte(data), &itm) if err != nil { ts.table.LogWithTableId("tablesink.useItem failed %v", data) return } roomUser := ts.getRoomUser(usr.GetUserId()) if roomUser == nil { ts.table.LogWithTableId("tablesink.useItem roomUser not found %d", usr.GetUserId()) return } bl := bullet.GetBullet(roomUser.getBulletId()) bulletOdds := ts.roomInfo.BulletMin if bl != nil { bulletOdds = bl.Odds } itm.UserId = usr.GetUserId() succeeded, _ := item.Consume(itm.UserId, itm.ItemId, 0, 1, 0) if !succeeded { // user类已经广播过失败的消息了 return } //coreservice.DoTaskAction(itm.UserId, task.TaskAction_user_item, 1) // 广播玩家信息 ts.broadCastUseItem(itm) extra := item.GetItemEffect(itm.ItemId) // 特殊道具后面处理 effectType := extra.SpecialType specialEffect := extra.SpecialEffect if specialEffect > 0 { // 如果是冰冻效果 if specialEffect == item.SpecialEffect_Frozen { ts.addEffecting(specialEffect, extra.Param1) // 延长所有鱼的生命 ts.fishmgr.addExtraLife(extra.Param1) } else { // 如果是激光道具 roomUser.addSpecial(itm.ItemId, bulletOdds, specialEffect, effectType, extra.Param1, extra.Param2) } } } func (ts *tablesink) specialCatch(usr *user.UserInfo, cmd, data string) { var sc fishcommon.SpecialCatch err := json.Unmarshal([]byte(data), &sc) if err != nil { ts.table.LogWithTableId("tablesink.specialCatch failed %v", data) return } roomUser := ts.getRoomUser(usr.GetUserId()) if roomUser == nil { ts.table.LogWithTableId("tablesink.specialCatch roomUser not found %d", usr.GetUserId()) return } for _, v := range sc.TargetFishKeys { catch := fishcommon.CatchFish{BulletKey: 0, FishKey: v} f := ts.fishmgr.getFish(v) if f == nil || f.IsDead() { ts.table.LogWithTableId("tablesink.specialCatch failed fish not found or dead %d", v) ts.sendCatchFailed(usr, catch, 0, true) continue } fi := fish.GetFishInfo(f.FishID) if fi == nil { ts.table.LogWithTableId("catshFish fishID[%d] invalid", f.FishID) continue } bulletOdds, power := roomUser.useSpecial(sc.OriginFishKey) if power == 0 { ts.table.LogWithTableId("specialCatch no power") // roomUser.removeSpecial(sc.OriginFishKey) return } // 计算是否捕获 var ret fishcommon.CatchFishRet ret.CatchFish = catch ret.BulletID = 0 ret.UserId = usr.GetUserId() isCatch := false for i := 0; i < power; i++ { isCatch = f.IsCatch(roomUser.getUserOdds(), ts.systemOdds, ts.roomInfo.OddsExtra) if isCatch { break } } ret.IsCatch = isCatch if !ret.IsCatch { ts.sendCatch(usr.GetUserIndex(), ret, true) continue } f.Status = fish.Fish_Dead ret.Coin = bulletOdds * f.GetOdds() ts.onCatchFish(fi, ret.Coin, usr.GetUserNickName()) // 是否产生道具 ret.ItemId, ret.ItemCount = ts.fishDrop.getDropItem(f.FishID) if ret.ItemCount > 0 { var items []item.ItemPack items = append(items, item.ItemPack{ItemId: ret.ItemId, Count: ret.ItemCount}) item.AddItems(usr.GetUserId(), items, "捕鱼掉落", common.LOGTYPE_FISH_DROP) } // 转盘鱼 ret.PrizeWheelItemId, ret.PrizeWheelItemCount = f.GetPrize() if ret.PrizeWheelItemCount > 0 { var items []item.ItemPack items = append(items, item.ItemPack{ItemId: ret.PrizeWheelItemId, Count: ret.PrizeWheelItemCount}) item.AddItems(usr.GetUserId(), items, "捕鱼转盘", common.LOGTYPE_FISH_DROP) } roomUser.specialUsed(sc.OriginFishKey, ret.Coin) if fi.SpecialType > 0 { // 如果是slot if fi.SpecialEffect == item.SpecialEffect_Slot { ret.SlotMultiple = fi.Param1 + rand.Intn(fi.Param2-fi.Param1) ret.Coin = bulletOdds * ret.SlotMultiple } else { roomUser.addSpecial(f.FishKey, bulletOdds, fi.SpecialEffect, fi.SpecialType, fi.Param1, fi.Param2) } } ts.broadcastCatch(ret, true) ts.table.LogWithTableId("specialCatch UserID[%d],BulletOdds[%d],Win[%d],FishID[%d]", ret.UserId, bulletOdds, ret.Coin, catch.FishKey) // 写分 ts.writeUserGold(usr, roomUser, ret.Coin) roomUser.setWaterPoolValue(ret.Coin, 0) // 加入纪录 ts.recordmgr.getUserRecord(ret.UserId).addRecord(f.FishID, 0, ret.Coin) } } func (ts *tablesink) specialShoot(usr *user.UserInfo, cmd, data string) { ts.broadcastData(cmd, data) } func (ts *tablesink) specialCatchEnd(usr *user.UserInfo, cmd, data string) { var sc fishcommon.SpecialCatchEnd err := json.Unmarshal([]byte(data), &sc) if err != nil { ts.table.LogWithTableId("tablesink.specialCatchEnd failed %v", data) return } sc.UserId = usr.GetUserId() roomUser := ts.getRoomUser(usr.GetUserId()) if roomUser == nil { ts.table.LogWithTableId("tablesink.specialCatchEnd roomUser not found %d", usr.GetUserId()) return } sc.TotalEarn = roomUser.removeSpecial(sc.OriginFishKey) d, _ := json.Marshal(sc) ts.broadcastData(cmd, string(d)) } func (ts *tablesink) upgradeBullet(usr *user.UserInfo, cmd, data string) { roomUser := ts.getRoomUser(usr.GetUserId()) if roomUser == nil { ts.table.LogWithTableId("tablesink.upgradeBullet roomUser not found %d", usr.GetUserId()) return } var ret fishcommon.UpgradeBullet_resp curBulletId := roomUser.getMaxBulletId() // 如果已经是最高等级了 if curBulletId == ts.roomInfo.BulletMax { ts.table.LogWithTableId("tablesink.upgradeBullet 已经是最高等级了") ret.Succeeded = false ret.ErrorMsg = "升级失败,已经是本房间最高等级" d, _ := json.Marshal(ret) ts.table.SendGameData(usr.GetUserIndex(), cmd, string(d)) return } count := bullet.GetUpgradeCount(curBulletId) if count == 0 { ts.table.LogWithTableId("tablesink.upgradeBullet failed count == 0") ret.Succeeded = false ret.ErrorMsg = "升级失败" d, _ := json.Marshal(ret) ts.table.SendGameData(usr.GetUserIndex(), cmd, string(d)) return } // 此处暂时写死 /* 原本需要扣除精华来升级子弹 itemId := common.ESSENCE_ITEMID ok, _ := user.UseItem(itemId, 0, count) if !ok { ret.Succeeded = false ret.ErrorMsg = "升级失败,精华不足!" d, _ := json.Marshal(ret) go user.WriteMsg(cmd, string(d)) return } */ ret.Succeeded = true d, _ := json.Marshal(ret) ts.table.SendGameData(usr.GetUserIndex(), cmd, string(d)) roomUser.setMaxBulletId(curBulletId + 1) ts.broadCastUserInfo(usr) } func (ts *tablesink) sendPoolValue() { ts.broadcastPoolValue = true } func (ts *tablesink) broadcastPool() { if true { return } if ts.prizePool == nil { return } data := fmt.Sprintf("%d", ts.prizePool.GetPoolValue()) ts.broadcastData(fishcommon.POOL_VALUE, data) } func (ts *tablesink) broadcastPoolDraw(draw fishcommon.PrizePoolDraw_resp) { data, _ := json.Marshal(draw) ts.broadcastData(fishcommon.POOL_DRAW, string(data)) } func (ts *tablesink) writeUserGold(usr *user.UserInfo, fUser *fishuser, amount int) bool { //ok, _ := ts.table.WriteUserMoney(userId, amount, tax, status, scoreType, ts.roomInfo.RoomName) // 这里不实际写分,只修改变量 gold := usr.GetUserGold() if gold+amount < 0 { return false } usr.SetUserGold(gold + amount) fUser.addScore(amount) return true } func (ts *tablesink) doWriteUserGold(fUser *fishuser) { consume, earn := fUser.getConsumeAndEarnAndClear() //ts.table.LogWithTableId("doWriteUserGold UserId[%d] consume[%d] earn[%d]", fUser.userId, consume, earn) if consume < 0 { ts.table.WriteUserMoney(fUser.userId, consume, 0, 0, 1, ts.roomInfo.RoomName) } if earn > 0 { ts.table.WriteUserMoney(fUser.userId, earn, 0, 0, 2, ts.roomInfo.RoomName) } } func (ts *tablesink) onTimerWriteScore() { ts.table.SetTimer(fishcommon.TIMER_WRITESCORE, fishcommon.TIME_WRITESCORE) for _, v := range ts.Users { if v != nil { go ts.doWriteUserGold(v) } } }