Compare commits

...

10 Commits

Author SHA1 Message Date
genxium
7a0127b17d Updated README. 2023-01-20 14:32:38 +08:00
genxium
59c8427c70 Enhanced turn-around performance. 2023-01-20 11:29:27 +08:00
genxium
c357ebad3b Updated README again. 2023-01-19 22:19:40 +08:00
genxium
b2e1f7c2a6 Updated README. 2023-01-19 10:45:48 +08:00
genxium
9a8c32197e Added TurnAroundFramesToRecover. 2023-01-19 09:20:52 +08:00
genxium
a82a238ce9 Added frontend log for inspection of "onPeerInputFrameUpsync". 2023-01-18 22:43:10 +08:00
genxium
5b76c5bbfb Minor fix. 2023-01-18 18:03:54 +08:00
genxium
b81c470135 Drafted peer inputFrameUpsync broadcasting mechanism. 2023-01-18 17:53:58 +08:00
genxium
48074d48af Misc fixes for UI alignments. 2023-01-18 12:22:12 +08:00
genxium
342efc623c Made frontend landscape. 2023-01-17 23:35:23 +08:00
48 changed files with 7305 additions and 6347 deletions

View File

@@ -67,3 +67,6 @@ To summarize, if UDP is used we need
## Additional hassles to care about using UDP
When using UDP, it's also necessary to verify authorization of each incoming packet, e.g. by simple time limited symmetric key, due to being connectionless.
## Why not hybrid?
Instead of replacing all use of TCP by UDP, it's more reasonable to keep using TCP for login and the "all-confirmed downsync inputFrames" from server to players (and possibly "upsync inputFrames" from player to server, but tradeoff on that remains to be discussed), while using UDP for broadcasting inputFrames of each individual player asap (either using p2p or not) just for **better prediction performance**!

View File

@@ -2,7 +2,14 @@
This project is a demo for a websocket-based rollback netcode inspired by [GGPO](https://github.com/pond3r/ggpo/blob/master/doc/README.md). As lots of feedbacks ask for a discussion on using UDP instead, I tried to summarize my personal opinion about it in [ConcerningEdgeCases](./ConcerningEdgeCases.md) -- not necessarily correct but that's indeed a question to face :)
The following video is recorded over INTERNET using an input delay of 4 frames and it feels SMOOTH when playing! Please also checkout [this demo video](https://pan.baidu.com/s/1ML6hNupaPHPJRd5rcTvQvw?pwd=8ruc) to see how this demo carries out a full 60fps synchronization with the help of _batched input upsync/downsync_ for satisfying network I/O performance.
The following video is recorded over INTERNET using an input delay of 4 frames and it feels SMOOTH when playing! Please also checkout these demo videos
- [source video of the first gif](https://pan.baidu.com/s/1ML6hNupaPHPJRd5rcTvQvw?pwd=8ruc)
- [phone v.s. PC over internet battle#1](https://pan.baidu.com/s/1NuGxuMwrV_jalcToyUZPLg?pwd=kfkr)
- [phone v.s. PC over internet battle#2](https://pan.baidu.com/s/1kMiFdwDHyJpZJ0GGU1Y3eA?pwd=46gd)
- [PC Wifi viewing Phone 4g](https://pan.baidu.com/s/1PJEtC9iB_fcabMWhbx2oAg?pwd=tp7k)
- [PC Wifi viewing Phone Wifi (over internet of course)](https://pan.baidu.com/s/108rvC1CcUdiQeMauXWsLJg?pwd=mn39)
to see how this demo carries out a full 60fps synchronization with the help of _batched input upsync/downsync_ for satisfying network I/O performance.
![gif_demo_1](./charts/internet_fireball_explosion_wallmove_spedup.gif)
@@ -67,7 +74,7 @@ user@proj-root/battle_srv/configs> cp -r ./configs.template ./configs
user@proj-root/frontend/assets/plugin_scripts> cp ./conf.js.template ./conf.js
```
## 1.2 Actual building & running
## 1.3 Actual building & running
### Backend
```
### The following command runs mysql-server in foreground, it's almost NEVER run in such a way, please find a proper way to run it for yourself
@@ -96,3 +103,11 @@ ErrFatal {"err": "MISCONF Redis is configured to save RDB snapshots, but
```
Just restart your `redis-server` process.
### 2.2 Why not show "PING value" on frontend display?
The most important reason for not showing "PING value" is simple: in most games the "PING value" is collected by a dedicated kernel thread which doesn't interfere the UI thread or the primary networking thread. As this demo primarily runs on browser by far, I don't have this capability easily.
Moreover, in practice I found that to spot sync anomalies, the following tools are much more useful than the "PING VALUE".
- Detection of [prediction mismatch on the frontend](https://github.com/genxium/DelayNoMore/blob/v0.9.19/frontend/assets/scripts/Map.js#L842).
- Detection of [type#1 forceConfirmation on the backend](https://github.com/genxium/DelayNoMore/blob/v0.9.19/battle_srv/models/room.go#L1246).
- Detection of [type#2 forceConfirmation on the backend](https://github.com/genxium/DelayNoMore/blob/v0.9.19/battle_srv/models/room.go#L1259).

View File

@@ -89,6 +89,7 @@ func setRouter(router *gin.Engine) {
router.StaticFS("/asset", http.Dir(filepath.Join(Conf.General.AppRoot, "asset")))
router.GET("/ping", f)
router.GET("/tsrht", ws.Serve)
router.GET("/tsrhtSecondary", ws.HandleSecondaryWsSessionForPlayer)
apiRouter := router.Group("/api")
{

View File

@@ -41,6 +41,7 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
CapturedByInertia: last.CapturedByInertia,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
@@ -165,6 +166,7 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
CapturedByInertia: last.CapturedByInertia,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
@@ -216,6 +218,7 @@ func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
CapturedByInertia: last.CapturedByInertia,
Score: last.Score,
Removed: last.Removed,
}

View File

@@ -27,10 +27,11 @@ const (
UPSYNC_MSG_ACT_PLAYER_CMD = int32(2)
UPSYNC_MSG_ACT_PLAYER_COLLIDER_ACK = int32(3)
DOWNSYNC_MSG_ACT_HB_REQ = int32(1)
DOWNSYNC_MSG_ACT_INPUT_BATCH = int32(2)
DOWNSYNC_MSG_ACT_BATTLE_STOPPED = int32(3)
DOWNSYNC_MSG_ACT_FORCED_RESYNC = int32(4)
DOWNSYNC_MSG_ACT_HB_REQ = int32(1)
DOWNSYNC_MSG_ACT_INPUT_BATCH = int32(2)
DOWNSYNC_MSG_ACT_BATTLE_STOPPED = int32(3)
DOWNSYNC_MSG_ACT_FORCED_RESYNC = int32(4)
DOWNSYNC_MSG_ACT_PEER_INPUT_BATCH = int32(5)
DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START = int32(-1)
DOWNSYNC_MSG_ACT_BATTLE_START = int32(0)
@@ -116,10 +117,15 @@ type Room struct {
*
* Moreover, during the invocation of `PlayerSignalToCloseDict`, the `Player` instance is supposed to be deallocated (though not synchronously).
*/
PlayerDownsyncSessionDict map[int32]*websocket.Conn
PlayerDownsyncChanDict map[int32](chan pb.InputsBufferSnapshot)
PlayerDownsyncSessionDict map[int32]*websocket.Conn
PlayerSignalToCloseDict map[int32]SignalToCloseConnCbType
PlayerDownsyncChanDict map[int32](chan pb.InputsBufferSnapshot)
PlayerSecondaryDownsyncSessionDict map[int32]*websocket.Conn
PlayerSecondarySignalToCloseDict map[int32]SignalToCloseConnCbType
PlayerSecondaryDownsyncChanDict map[int32](chan pb.InputsBufferSnapshot)
PlayerActiveWatchdogDict map[int32](*Watchdog)
PlayerSignalToCloseDict map[int32]SignalToCloseConnCbType
Score float32
State int32
Index int
@@ -184,7 +190,7 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
newWatchdog := NewWatchdog(ConstVals.Ws.WillKickIfInactiveFor, func() {
Logger.Warn("Conn inactive watchdog triggered#1:", zap.Any("playerId", playerId), zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount))
signalToCloseConnOfThisPlayer(Constants.RetCode.ActiveWatchdog, "")
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.ActiveWatchdog)
})
newWatchdog.Stop()
pR.PlayerActiveWatchdogDict[playerId] = newWatchdog
@@ -221,7 +227,7 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
pR.PlayerActiveWatchdogDict[playerId] = NewWatchdog(ConstVals.Ws.WillKickIfInactiveFor, func() {
Logger.Warn("Conn inactive watchdog triggered#2:", zap.Any("playerId", playerId), zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount))
signalToCloseConnOfThisPlayer(Constants.RetCode.ActiveWatchdog, "")
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.ActiveWatchdog)
}) // For ReAdded player the new watchdog starts immediately
Logger.Warn("ReAddPlayerIfPossible finished.", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("joinIndex", pEffectiveInRoomPlayerInstance.JoinIndex), zap.Any("playerBattleState", pEffectiveInRoomPlayerInstance.BattleState), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount), zap.Any("AckingFrameId", pEffectiveInRoomPlayerInstance.AckingFrameId), zap.Any("AckingInputFrameId", pEffectiveInRoomPlayerInstance.AckingInputFrameId), zap.Any("LastSentInputFrameId", pEffectiveInRoomPlayerInstance.LastSentInputFrameId))
@@ -482,7 +488,7 @@ func (pR *Room) StartBattle() {
kickoffFrameJs := pR.RenderFrameBuffer.GetByFrameId(0).(*battle.RoomDownsyncFrame)
pbKickOffRenderFrame := toPbRoomDownsyncFrame(kickoffFrameJs)
pbKickOffRenderFrame.SpeciesIdList = pR.SpeciesIdList
pR.sendSafely(pbKickOffRenderFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
pR.sendSafely(pbKickOffRenderFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true, MAGIC_JOIN_INDEX_DEFAULT)
}
Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id))
}
@@ -509,7 +515,7 @@ func (pR *Room) StartBattle() {
}
}
downsyncLoop := func(playerId int32, player *Player, playerDownsyncChan chan pb.InputsBufferSnapshot) {
downsyncLoop := func(playerId int32, player *Player, playerDownsyncChan chan pb.InputsBufferSnapshot, playerSecondaryDownsyncChan chan pb.InputsBufferSnapshot) {
defer func() {
if r := recover(); r != nil {
Logger.Error("downsyncLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("panic", r))
@@ -517,19 +523,23 @@ func (pR *Room) StartBattle() {
Logger.Info(fmt.Sprintf("The `downsyncLoop` for (roomId=%v, playerId=%v) is stopped@renderFrameId=%v", pR.Id, playerId, pR.RenderFrameId))
}()
Logger.Debug(fmt.Sprintf("Started downsyncLoop for (roomId: %d, playerId:%d, playerDownsyncChan:%p)", pR.Id, playerId, playerDownsyncChan))
//Logger.Info(fmt.Sprintf("Started downsyncLoop for (roomId: %d, playerId:%d, playerDownsyncChan:%p)", pR.Id, playerId, playerDownsyncChan))
for {
nowBattleState := atomic.LoadInt32(&pR.State)
switch nowBattleState {
case RoomBattleStateIns.IDLE, RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT, RoomBattleStateIns.IN_SETTLEMENT, RoomBattleStateIns.IN_DISMISSAL:
Logger.Warn(fmt.Sprintf("Battle is not waiting/preparing/active for playerDownsyncChan for (roomId: %d, playerId:%d)", pR.Id, playerId))
return
}
select {
case inputsBufferSnapshot := <-playerDownsyncChan:
nowBattleState := atomic.LoadInt32(&pR.State)
switch nowBattleState {
case RoomBattleStateIns.IDLE, RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT, RoomBattleStateIns.IN_SETTLEMENT, RoomBattleStateIns.IN_DISMISSAL:
Logger.Warn(fmt.Sprintf("Battle is not waiting/preparing/active for playerDownsyncChan for (roomId: %d, playerId:%d)", pR.Id, playerId))
return
}
pR.downsyncToSinglePlayer(playerId, player, inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, inputsBufferSnapshot.ToSendInputFrameDownsyncs, inputsBufferSnapshot.ShouldForceResync)
//Logger.Info(fmt.Sprintf("Sent inputsBufferSnapshot(refRenderFrameId:%d, unconfirmedMask:%v) to for (roomId: %d, playerId:%d)#2", inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, pR.Id, playerId))
case inputsBufferSnapshot2 := <-playerSecondaryDownsyncChan:
pR.downsyncPeerInputFrameUpsyncToSinglePlayer(playerId, player, inputsBufferSnapshot2.ToSendInputFrameDownsyncs, inputsBufferSnapshot2.PeerJoinIndex)
//Logger.Info(fmt.Sprintf("Sent secondary inputsBufferSnapshot to for (roomId: %d, playerId:%d)#2", pR.Id, playerId))
default:
}
}
@@ -542,7 +552,8 @@ func (pR *Room) StartBattle() {
Each "playerDownsyncChan" stays alive through out the lifecycle of room instead of each "playerDownsyncSession", i.e. not closed or dereferenced upon disconnection.
*/
pR.PlayerDownsyncChanDict[playerId] = make(chan pb.InputsBufferSnapshot, pR.InputsBuffer.N)
go downsyncLoop(playerId, player, pR.PlayerDownsyncChanDict[playerId])
pR.PlayerSecondaryDownsyncChanDict[playerId] = make(chan pb.InputsBufferSnapshot, pR.InputsBuffer.N)
go downsyncLoop(playerId, player, pR.PlayerDownsyncChanDict[playerId], pR.PlayerSecondaryDownsyncChanDict[playerId])
}
pR.onBattlePrepare(func() {
@@ -599,6 +610,16 @@ func (pR *Room) OnBattleCmdReceived(pReq *pb.WsReq) {
inputsBufferSnapshot := pR.markConfirmationIfApplicable(inputFrameUpsyncBatch, playerId, player)
if nil != inputsBufferSnapshot {
pR.downsyncToAllPlayers(inputsBufferSnapshot)
} else {
// no new all-confirmed
toSendInputFrameDownsyncs := pR.cloneInputsBuffer(inputFrameUpsyncBatch[0].InputFrameId, inputFrameUpsyncBatch[len(inputFrameUpsyncBatch)-1].InputFrameId+1)
inputsBufferSnapshot = &pb.InputsBufferSnapshot{
ToSendInputFrameDownsyncs: toSendInputFrameDownsyncs,
PeerJoinIndex: player.JoinIndex,
}
//Logger.Info(fmt.Sprintf("OnBattleCmdReceived no new all-confirmed: roomId=%v, fromPlayerId=%v, forming peer broadcasting snapshot=%v", pR.Id, playerId, inputsBufferSnapshot))
pR.broadcastPeerUpsyncForBetterPrediction(inputsBufferSnapshot)
}
}
@@ -650,7 +671,7 @@ func (pR *Room) StopBattleForSettlement() {
PlayersArr: toPbPlayers(pR.Players, false),
CountdownNanos: -1, // TODO: Replace this magic constant!
}
pR.sendSafely(&assembledFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_STOPPED, playerId, true)
pR.sendSafely(&assembledFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_STOPPED, playerId, true, MAGIC_JOIN_INDEX_DEFAULT)
}
// Note that `pR.onBattleStoppedForSettlement` will be called by `battleMainLoop`.
}
@@ -679,7 +700,7 @@ func (pR *Room) onBattlePrepare(cb BattleStartCbType) {
Logger.Info("Sending out frame for RoomBattleState.PREPARE:", zap.Any("battleReadyToStartFrame", battleReadyToStartFrame))
for _, player := range pR.Players {
pR.sendSafely(battleReadyToStartFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START, player.Id, true)
pR.sendSafely(battleReadyToStartFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START, player.Id, true, MAGIC_JOIN_INDEX_DEFAULT)
}
battlePreparationNanos := int64(6000000000)
@@ -748,6 +769,7 @@ func (pR *Room) OnDismissed() {
pR.CharacterConfigsArr = make([]*battle.CharacterConfig, pR.Capacity)
pR.CollisionSysMap = make(map[int32]*resolv.Object)
pR.PlayerDownsyncSessionDict = make(map[int32]*websocket.Conn)
pR.PlayerSecondaryDownsyncSessionDict = make(map[int32]*websocket.Conn)
for _, oldWatchdog := range pR.PlayerActiveWatchdogDict {
oldWatchdog.Stop()
}
@@ -756,7 +778,12 @@ func (pR *Room) OnDismissed() {
close(oldChan)
}
pR.PlayerDownsyncChanDict = make(map[int32](chan pb.InputsBufferSnapshot))
for _, oldChan := range pR.PlayerSecondaryDownsyncChanDict {
close(oldChan)
}
pR.PlayerSecondaryDownsyncChanDict = make(map[int32](chan pb.InputsBufferSnapshot))
pR.PlayerSignalToCloseDict = make(map[int32]SignalToCloseConnCbType)
pR.PlayerSecondarySignalToCloseDict = make(map[int32]SignalToCloseConnCbType)
pR.JoinIndexBooleanArr = make([]bool, pR.Capacity)
pR.RenderCacheSize = 1024
pR.RenderFrameBuffer = battle.NewRingBuffer(pR.RenderCacheSize)
@@ -781,7 +808,7 @@ func (pR *Room) OnDismissed() {
pR.BattleDurationFrames = int32(60 * serverFps)
pR.BattleDurationNanos = int64(pR.BattleDurationFrames) * (pR.RollbackEstimatedDtNanos + 1)
pR.InputFrameUpsyncDelayTolerance = battle.ConvertToNoDelayInputFrameId(pR.NstDelayFrames) - 1 // this value should be strictly smaller than (NstDelayFrames >> InputScaleFrames), otherwise "type#1 forceConfirmation" might become a lag avalanche
pR.MaxChasingRenderFramesPerUpdate = 12 // Don't set this value too high to avoid exhausting frontend CPU within a single frame
pR.MaxChasingRenderFramesPerUpdate = 4 // Don't set this value too high to avoid exhausting frontend CPU within a single frame
pR.BackendDynamicsEnabled = true // [WARNING] When "false", recovery upon reconnection wouldn't work!
pR.ForceAllResyncOnAnyActiveSlowTicker = true // See tradeoff discussion in "downsyncToAllPlayers"
@@ -799,19 +826,24 @@ func (pR *Room) OnDismissed() {
}
func (pR *Room) expelPlayerDuringGame(playerId int32) {
if signalToCloseConnOfThisPlayer, existent := pR.PlayerSignalToCloseDict[playerId]; existent {
signalToCloseConnOfThisPlayer(Constants.RetCode.UnknownError, "") // TODO: Specify an error code
}
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.UnknownError)
pR.onPlayerExpelledDuringGame(playerId)
}
func (pR *Room) expelPlayerForDismissal(playerId int32) {
if signalToCloseConnOfThisPlayer, existent := pR.PlayerSignalToCloseDict[playerId]; existent {
signalToCloseConnOfThisPlayer(Constants.RetCode.UnknownError, "") // TODO: Specify an error code
}
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.UnknownError)
pR.onPlayerExpelledForDismissal(playerId)
}
func (pR *Room) signalToCloseAllSessionsOfPlayer(playerId int32, retCode int) {
if signalToCloseConnOfThisPlayer, existent := pR.PlayerSignalToCloseDict[playerId]; existent {
signalToCloseConnOfThisPlayer(retCode, "") // TODO: Specify an error code
}
if signalToCloseConnOfThisPlayer2, existent2 := pR.PlayerSecondarySignalToCloseDict[playerId]; existent2 {
signalToCloseConnOfThisPlayer2(retCode, "") // TODO: Specify an error code
}
}
func (pR *Room) onPlayerExpelledDuringGame(playerId int32) {
pR.onPlayerLost(playerId)
}
@@ -829,6 +861,10 @@ func (pR *Room) OnPlayerDisconnected(playerId int32) {
}
}()
if signalToCloseConnOfThisPlayer2, existent2 := pR.PlayerSecondarySignalToCloseDict[playerId]; existent2 {
signalToCloseConnOfThisPlayer2(Constants.RetCode.UnknownError, "") // TODO: Specify an error code
}
if player, existent := pR.Players[playerId]; existent {
thatPlayerBattleState := atomic.LoadInt32(&(player.BattleState))
switch thatPlayerBattleState {
@@ -888,6 +924,8 @@ func (pR *Room) clearPlayerNetworkSession(playerId int32) {
delete(pR.PlayerActiveWatchdogDict, playerId)
delete(pR.PlayerDownsyncSessionDict, playerId)
delete(pR.PlayerSignalToCloseDict, playerId)
delete(pR.PlayerSecondaryDownsyncSessionDict, playerId)
delete(pR.PlayerSecondarySignalToCloseDict, playerId)
}
}
@@ -977,7 +1015,7 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
Logger.Debug(fmt.Sprintf("OnPlayerBattleColliderAcked-middle: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, thatPlayerId=%v, thatPlayerBattleState=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, thatPlayer.Id, thatPlayerBattleState))
if thatPlayerId == targetPlayer.Id || (PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK == thatPlayerBattleState || PlayerBattleStateIns.ACTIVE == thatPlayerBattleState) {
Logger.Debug(fmt.Sprintf("OnPlayerBattleColliderAcked-sending DOWNSYNC_MSG_ACT_PLAYER_ADDED_AND_ACKED: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, capacity=%v, EffectivePlayerCount=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, pR.Capacity, pR.EffectivePlayerCount))
pR.sendSafely(playerAckedFrame, nil, DOWNSYNC_MSG_ACT_PLAYER_ADDED_AND_ACKED, thatPlayer.Id, true)
pR.sendSafely(playerAckedFrame, nil, DOWNSYNC_MSG_ACT_PLAYER_ADDED_AND_ACKED, thatPlayer.Id, true, MAGIC_JOIN_INDEX_DEFAULT)
}
}
atomic.StoreInt32(&(targetPlayer.BattleState), PlayerBattleStateIns.ACTIVE)
@@ -1010,28 +1048,43 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
return true
}
func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputFrameDownsyncs []*pb.InputFrameDownsync, act int32, playerId int32, needLockExplicitly bool) {
func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputFrameDownsyncs []*pb.InputFrameDownsync, act int32, playerId int32, needLockExplicitly bool, peerJoinIndex int32) {
defer func() {
if r := recover(); r != nil {
Logger.Error("sendSafely, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("panic", r))
}
}()
if playerDownsyncSession, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
pResp := &pb.WsResp{
Ret: int32(Constants.RetCode.Ok),
Act: act,
Rdf: roomDownsyncFrame,
InputFrameDownsyncBatch: toSendInputFrameDownsyncs,
}
pResp := &pb.WsResp{
Ret: int32(Constants.RetCode.Ok),
Act: act,
Rdf: roomDownsyncFrame,
InputFrameDownsyncBatch: toSendInputFrameDownsyncs,
PeerJoinIndex: peerJoinIndex,
}
theBytes, marshalErr := proto.Marshal(pResp)
if nil != marshalErr {
panic(fmt.Sprintf("Error marshaling downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
}
theBytes, marshalErr := proto.Marshal(pResp)
if nil != marshalErr {
panic(fmt.Sprintf("Error marshaling downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
}
if err := playerDownsyncSession.WriteMessage(websocket.BinaryMessage, theBytes); nil != err {
panic(fmt.Sprintf("Error sending downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v, err=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount, err))
if MAGIC_JOIN_INDEX_DEFAULT == peerJoinIndex {
if playerDownsyncSession, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
if err := playerDownsyncSession.WriteMessage(websocket.BinaryMessage, theBytes); nil != err {
panic(fmt.Sprintf("Error sending primary downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v, err=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount, err))
}
}
} else {
/*
[FIXME]
This branch is preferred to use an additional session of each player for sending, and the session is preferrably UDP instead of any TCP-based protocol, but I'm being lazy here.
See `<proj-root>/ConcerningEdgeCases.md` for the advantage of using UDP as a supplement.
*/
if playerSecondaryDownsyncSession, existent := pR.PlayerSecondaryDownsyncSessionDict[playerId]; existent {
if err := playerSecondaryDownsyncSession.WriteMessage(websocket.BinaryMessage, theBytes); nil != err {
panic(fmt.Sprintf("Error sending secondary downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v, err=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount, err))
}
}
}
}
@@ -1347,6 +1400,30 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
}
}
func (pR *Room) broadcastPeerUpsyncForBetterPrediction(inputsBufferSnapshot *pb.InputsBufferSnapshot) {
// See `<proj-root>/ConcerningEdgeCases.md` for why this method exists.
for _, player := range pR.PlayersArr {
playerBattleState := atomic.LoadInt32(&(player.BattleState))
switch playerBattleState {
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
continue
}
if player.JoinIndex == inputsBufferSnapshot.PeerJoinIndex {
continue
}
if playerSecondaryDownsyncChan, existent := pR.PlayerSecondaryDownsyncChanDict[player.Id]; existent {
/*
[FIXME]
This function is preferred to use an additional go-channel of each player for sending, see "downsyncLoop" & "Room.sendSafely" for more information!
*/
playerSecondaryDownsyncChan <- (*inputsBufferSnapshot)
} else {
Logger.Warn(fmt.Sprintf("playerDownsyncChan for (roomId: %d, playerId:%d) is gone", pR.Id, player.Id))
}
}
}
func (pR *Room) downsyncToAllPlayers(inputsBufferSnapshot *pb.InputsBufferSnapshot) {
/*
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is LOCKED to **preserve the order of generation of "inputsBufferSnapshot" for sending** -- see comments in "OnBattleCmdReceived" and [this issue](https://github.com/genxium/DelayNoMore/issues/12).
@@ -1423,14 +1500,14 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
We hereby assume that Golang runtime allocates & frees small amount of RAM quickly enough compared to either network I/O blocking in worst cases or the high frequency "per inputFrameDownsync*player" locking (though "OnBattleCmdReceived" locks at the same frequency but it's inevitable).
*/
playerJoinIndex := player.JoinIndex - 1
playerJoinIndexInBooleanArr := player.JoinIndex - 1
playerBattleState := atomic.LoadInt32(&(player.BattleState))
switch playerBattleState {
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
return
}
isSlowTicker := (0 < (unconfirmedMask & uint64(1<<uint32(playerJoinIndex))))
isSlowTicker := (0 < (unconfirmedMask & uint64(1<<uint32(playerJoinIndexInBooleanArr))))
shouldResync1 := (PlayerBattleStateIns.READDED_BATTLE_COLLIDER_ACKED == playerBattleState) // i.e. implies that "MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId"
shouldResync2 := isSlowTicker // This condition is critical, if we don't send resync upon this condition, the "reconnected or slowly-clocking player" might never get its input synced
shouldResync3 := shouldForceResync
@@ -1455,13 +1532,13 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
refRenderFrame.BackendUnconfirmedMask = unconfirmedMask
pbRefRenderFrame := toPbRoomDownsyncFrame(refRenderFrame)
pbRefRenderFrame.SpeciesIdList = pR.SpeciesIdList
pR.sendSafely(pbRefRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false)
pR.sendSafely(pbRefRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false, MAGIC_JOIN_INDEX_DEFAULT)
//Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: InputsBuffer=%v", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, pR.InputsBufferString(false)))
if shouldResync1 || shouldResync3 {
Logger.Debug(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: shouldResync1=%v, shouldResync2=%v, shouldResync3=%v, playerBattleState=%d", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, shouldResync1, shouldResync2, shouldResync3, playerBattleState))
}
} else {
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_INPUT_BATCH, playerId, false)
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_INPUT_BATCH, playerId, false, MAGIC_JOIN_INDEX_DEFAULT)
}
player.LastSentInputFrameId = toSendInputFrameIdEd - 1
if shouldResync1 {
@@ -1469,6 +1546,16 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
}
}
func (pR *Room) downsyncPeerInputFrameUpsyncToSinglePlayer(playerId int32, player *Player, toSendInputFrameDownsyncsSnapshot []*pb.InputFrameDownsync, peerJoinIndex int32) {
playerBattleState := atomic.LoadInt32(&(player.BattleState))
switch playerBattleState {
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
return
}
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_PEER_INPUT_BATCH, playerId, false, peerJoinIndex)
}
func (pR *Room) cloneInputsBuffer(stFrameId, edFrameId int32) []*pb.InputFrameDownsync {
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
cloned := make([]*pb.InputFrameDownsync, 0, edFrameId-stFrameId)
@@ -1501,3 +1588,22 @@ func (pR *Room) cloneInputsBuffer(stFrameId, edFrameId int32) []*pb.InputFrameDo
return cloned
}
func (pR *Room) SetSecondarySession(playerId int32, session *websocket.Conn, signalToCloseConnOfThisPlayer SignalToCloseConnCbType) {
// TODO: Use a dedicated lock
if player, ok := pR.Players[playerId]; ok {
playerBattleState := atomic.LoadInt32(&(player.BattleState))
switch playerBattleState {
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
// Kindly note that "PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK" are allowed
return
}
if _, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
if _, existent2 := pR.PlayerSecondaryDownsyncSessionDict[playerId]; !existent2 {
Logger.Info(fmt.Sprintf("SetSecondarySession for roomId=%v, playerId=%d, pR.Players=%v", pR.Id, playerId, pR.Players))
pR.PlayerSecondaryDownsyncSessionDict[playerId] = session
pR.PlayerSecondarySignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
}
}
}
}

View File

@@ -30,9 +30,9 @@ type PlayerDownsync struct {
VirtualGridX int32 `protobuf:"varint,2,opt,name=virtualGridX,proto3" json:"virtualGridX,omitempty"`
VirtualGridY int32 `protobuf:"varint,3,opt,name=virtualGridY,proto3" json:"virtualGridY,omitempty"`
DirX int32 `protobuf:"varint,4,opt,name=dirX,proto3" json:"dirX,omitempty"`
DirY int32 `protobuf:"varint,5,opt,name=dirY,proto3" json:"dirY,omitempty"` // "dirX" and "dirY" determines character facing
DirY int32 `protobuf:"varint,5,opt,name=dirY,proto3" json:"dirY,omitempty"`
VelX int32 `protobuf:"varint,6,opt,name=velX,proto3" json:"velX,omitempty"`
VelY int32 `protobuf:"varint,7,opt,name=velY,proto3" json:"velY,omitempty"` // "velX" and "velY" is used to record the accumulated effect by accelerations (including gravity)
VelY int32 `protobuf:"varint,7,opt,name=velY,proto3" json:"velY,omitempty"` // "velX" and "velY" is used to record the accumulated effect by inertia and accelerations (including gravity)
Speed int32 `protobuf:"varint,8,opt,name=speed,proto3" json:"speed,omitempty"` // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
BattleState int32 `protobuf:"varint,9,opt,name=battleState,proto3" json:"battleState,omitempty"`
JoinIndex int32 `protobuf:"varint,10,opt,name=joinIndex,proto3" json:"joinIndex,omitempty"`
@@ -54,6 +54,7 @@ type PlayerDownsync struct {
OnWall bool `protobuf:"varint,26,opt,name=onWall,proto3" json:"onWall,omitempty"` // like "inAir", its by design a standalone field only inferred by the collision result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "onWall (prev -> curr)"
OnWallNormX int32 `protobuf:"varint,27,opt,name=onWallNormX,proto3" json:"onWallNormX,omitempty"`
OnWallNormY int32 `protobuf:"varint,28,opt,name=onWallNormY,proto3" json:"onWallNormY,omitempty"`
CapturedByInertia bool `protobuf:"varint,29,opt,name=capturedByInertia,proto3" json:"capturedByInertia,omitempty"` // like "inAir", its by design a standalone field only inferred by the calc result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState"
Name string `protobuf:"bytes,997,opt,name=name,proto3" json:"name,omitempty"`
DisplayName string `protobuf:"bytes,998,opt,name=displayName,proto3" json:"displayName,omitempty"`
Avatar string `protobuf:"bytes,999,opt,name=avatar,proto3" json:"avatar,omitempty"`
@@ -287,6 +288,13 @@ func (x *PlayerDownsync) GetOnWallNormY() int32 {
return 0
}
func (x *PlayerDownsync) GetCapturedByInertia() bool {
if x != nil {
return x.CapturedByInertia
}
return false
}
func (x *PlayerDownsync) GetName() string {
if x != nil {
return x.Name
@@ -386,6 +394,7 @@ type InputFrameUpsync struct {
InputFrameId int32 `protobuf:"varint,1,opt,name=inputFrameId,proto3" json:"inputFrameId,omitempty"`
Encoded uint64 `protobuf:"varint,2,opt,name=encoded,proto3" json:"encoded,omitempty"`
JoinIndex int32 `protobuf:"varint,3,opt,name=joinIndex,proto3" json:"joinIndex,omitempty"`
}
func (x *InputFrameUpsync) Reset() {
@@ -434,6 +443,13 @@ func (x *InputFrameUpsync) GetEncoded() uint64 {
return 0
}
func (x *InputFrameUpsync) GetJoinIndex() int32 {
if x != nil {
return x.JoinIndex
}
return 0
}
type InputFrameDownsync struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -658,6 +674,7 @@ type WsResp struct {
Rdf *RoomDownsyncFrame `protobuf:"bytes,4,opt,name=rdf,proto3" json:"rdf,omitempty"`
InputFrameDownsyncBatch []*InputFrameDownsync `protobuf:"bytes,5,rep,name=inputFrameDownsyncBatch,proto3" json:"inputFrameDownsyncBatch,omitempty"`
BciFrame *BattleColliderInfo `protobuf:"bytes,6,opt,name=bciFrame,proto3" json:"bciFrame,omitempty"`
PeerJoinIndex int32 `protobuf:"varint,7,opt,name=peerJoinIndex,proto3" json:"peerJoinIndex,omitempty"` // Only used when "InputsBufferSnapshot.peerJoinIndex" is used.
}
func (x *WsResp) Reset() {
@@ -734,6 +751,13 @@ func (x *WsResp) GetBciFrame() *BattleColliderInfo {
return nil
}
func (x *WsResp) GetPeerJoinIndex() int32 {
if x != nil {
return x.PeerJoinIndex
}
return 0
}
type InputsBufferSnapshot struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -743,6 +767,7 @@ type InputsBufferSnapshot struct {
UnconfirmedMask uint64 `protobuf:"varint,2,opt,name=unconfirmedMask,proto3" json:"unconfirmedMask,omitempty"`
ToSendInputFrameDownsyncs []*InputFrameDownsync `protobuf:"bytes,3,rep,name=toSendInputFrameDownsyncs,proto3" json:"toSendInputFrameDownsyncs,omitempty"`
ShouldForceResync bool `protobuf:"varint,4,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"`
PeerJoinIndex int32 `protobuf:"varint,5,opt,name=peerJoinIndex,proto3" json:"peerJoinIndex,omitempty"` // Only used when "WsResp.peerJoinIndex" is used.
}
func (x *InputsBufferSnapshot) Reset() {
@@ -805,6 +830,13 @@ func (x *InputsBufferSnapshot) GetShouldForceResync() bool {
return false
}
func (x *InputsBufferSnapshot) GetPeerJoinIndex() int32 {
if x != nil {
return x.PeerJoinIndex
}
return 0
}
type MeleeBullet struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1592,7 +1624,7 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
0x0a, 0x19, 0x72, 0x6f, 0x6f, 0x6d, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x5f,
0x66, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x73, 0x1a, 0x0e, 0x67, 0x65, 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0xc5, 0x07, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f,
0x6f, 0x74, 0x6f, 0x22, 0xf3, 0x07, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f,
0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61,
0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x76, 0x69,
@@ -1647,288 +1679,297 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
0x4e, 0x6f, 0x72, 0x6d, 0x58, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f, 0x6e, 0x57,
0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x58, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x6e, 0x57, 0x61,
0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x59, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f,
0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x59, 0x12, 0x13, 0x0a, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0xe5, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x21, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0xe6,
0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61,
0x6d, 0x65, 0x12, 0x17, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0xe7, 0x07, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x6f, 0x0a, 0x11, 0x49,
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64,
0x12, 0x0e, 0x0a, 0x02, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x78,
0x12, 0x0e, 0x0a, 0x02, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x79,
0x12, 0x1c, 0x0a, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20,
0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1c,
0x0a, 0x09, 0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28,
0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x50, 0x0a, 0x10,
0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63,
0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x59, 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x61,
0x70, 0x74, 0x75, 0x72, 0x65, 0x64, 0x42, 0x79, 0x49, 0x6e, 0x65, 0x72, 0x74, 0x69, 0x61, 0x18,
0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x64, 0x42,
0x79, 0x49, 0x6e, 0x65, 0x72, 0x74, 0x69, 0x61, 0x12, 0x13, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x18, 0xe5, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a,
0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0xe6, 0x07, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x17, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0xe7, 0x07, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x6f, 0x0a, 0x11, 0x49, 0x6e, 0x70,
0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x12, 0x0e,
0x0a, 0x02, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x78, 0x12, 0x0e,
0x0a, 0x02, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x79, 0x12, 0x1c,
0x0a, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09,
0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
0x09, 0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x6e, 0x0a, 0x10, 0x49, 0x6e,
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22,
0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09,
0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e,
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63,
0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x18,
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x22, 0x7c,
0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e,
0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72,
0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f,
0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12,
0x28, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xb8, 0x02, 0x0a, 0x05, 0x57, 0x73,
0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61,
0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61,
0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01,
0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49,
0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e,
0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x63,
0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x61,
0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49,
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x4e, 0x0a, 0x15, 0x69,
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42,
0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70,
0x73, 0x79, 0x6e, 0x63, 0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x27, 0x0a, 0x02, 0x68,
0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63,
0x52, 0x02, 0x68, 0x62, 0x22, 0x89, 0x02, 0x0a, 0x06, 0x57, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12,
0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65,
0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73,
0x67, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d,
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72,
0x64, 0x66, 0x12, 0x54, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70,
0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52,
0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73,
0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64,
0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x22, 0xf4, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65,
0x72, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x66,
0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x05, 0x52, 0x10, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f,
0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12,
0x58, 0x0a, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75,
0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x19,
0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x68, 0x6f,
0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x04,
0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63,
0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x22, 0x89, 0x07, 0x0a, 0x0b, 0x4d, 0x65, 0x6c, 0x65,
0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69,
0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69,
0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66,
0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c,
0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c,
0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74,
0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74,
0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12,
0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53,
0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73,
0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a,
0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c,
0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28,
0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c,
0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a,
0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0d, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c,
0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65,
0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78,
0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f,
0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d,
0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x12, 0x20, 0x0a,
0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x18, 0x10, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x12,
0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x59, 0x18, 0x11,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65,
0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28,
0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x61,
0x6d, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49,
0x64, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74,
0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x69,
0x65, 0x73, 0x49, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x70, 0x65, 0x63,
0x69, 0x65, 0x73, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69,
0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f,
0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12,
0x18, 0x0a, 0x07, 0x62, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x05,
0x52, 0x07, 0x62, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72, 0x61,
0x6d, 0x65, 0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x18, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53, 0x74,
0x61, 0x74, 0x65, 0x22, 0xc1, 0x08, 0x0a, 0x0e, 0x46, 0x69, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x6c,
0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61,
0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e,
0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66, 0x66,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24,
0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18,
0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61,
0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61,
0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69,
0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x53,
0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x28,
0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74,
0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68,
0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c,
0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a, 0x0c,
0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0a, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59,
0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05,
0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66,
0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c,
0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a, 0x0c,
0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0d, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59,
0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74,
0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f,
0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78,
0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68,
0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x12, 0x20, 0x0a, 0x0b,
0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x18, 0x10, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x12, 0x20,
0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x59, 0x18, 0x11, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x59,
0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08,
0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x61, 0x6d,
0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64,
0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49,
0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c,
0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65,
0x73, 0x49, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x70, 0x65, 0x63, 0x69,
0x65, 0x73, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, 0x6f,
0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x65,
0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x18,
0x0a, 0x07, 0x62, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x05, 0x52,
0x07, 0x62, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72, 0x61, 0x6d,
0x65, 0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53, 0x74, 0x61,
0x74, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69,
0x64, 0x58, 0x18, 0xe7, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75,
0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x12, 0x23, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75,
0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x18, 0xe8, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c,
0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x12, 0x13, 0x0a, 0x04,
0x64, 0x69, 0x72, 0x58, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x69, 0x72,
0x58, 0x12, 0x13, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x59, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x05,
0x52, 0x04, 0x64, 0x69, 0x72, 0x59, 0x12, 0x13, 0x0a, 0x04, 0x76, 0x65, 0x6c, 0x58, 0x18, 0xeb,
0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x76, 0x65, 0x6c, 0x58, 0x12, 0x13, 0x0a, 0x04, 0x76,
0x65, 0x6c, 0x59, 0x18, 0xec, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x76, 0x65, 0x6c, 0x59,
0x12, 0x15, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0xed, 0x07, 0x20, 0x01, 0x28, 0x05,
0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0xc9, 0x05, 0x0a, 0x12, 0x42, 0x61, 0x74, 0x74,
0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c,
0x0a, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f, 0x50, 0x69, 0x6e, 0x67, 0x18, 0x02,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f,
0x50, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x15, 0x77, 0x69, 0x6c, 0x6c, 0x4b, 0x69, 0x63, 0x6b,
0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x6f, 0x72, 0x18, 0x03, 0x20,
0x01, 0x28, 0x05, 0x52, 0x15, 0x77, 0x69, 0x6c, 0x6c, 0x4b, 0x69, 0x63, 0x6b, 0x49, 0x66, 0x49,
0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x6f,
0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x13,
0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61,
0x6e, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c,
0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x46,
0x0a, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79,
0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65,
0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x6f, 0x6c,
0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61,
0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52,
0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64, 0x65,
0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x12, 0x3c, 0x0a, 0x19, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69,
0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x08, 0x20,
0x01, 0x28, 0x01, 0x52, 0x19, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74,
0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12, 0x3a,
0x0a, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61,
0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03,
0x52, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61,
0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65,
0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65,
0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66,
0x73, 0x65, 0x74, 0x58, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x73, 0x70, 0x61, 0x63,
0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x70, 0x61, 0x63,
0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c,
0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x12, 0x2a, 0x0a, 0x10,
0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73,
0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69,
0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c,
0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x72,
0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x28, 0x0a, 0x0f, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01,
0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xb8, 0x02, 0x0a, 0x05, 0x57, 0x73, 0x52, 0x65, 0x71, 0x12,
0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49,
0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03,
0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78,
0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65,
0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e,
0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20,
0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x4e, 0x0a, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68,
0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63,
0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79,
0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x27, 0x0a, 0x02, 0x68, 0x62, 0x18, 0x08, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61,
0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x02, 0x68, 0x62,
0x22, 0xaf, 0x02, 0x0a, 0x06, 0x57, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x72,
0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x20, 0x0a,
0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x12,
0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63,
0x74, 0x12, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e,
0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72, 0x64, 0x66, 0x12, 0x54,
0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e,
0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x17, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42,
0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d,
0x70, 0x65, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x07, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64,
0x65, 0x78, 0x22, 0x9a, 0x02, 0x0a, 0x14, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x42, 0x75, 0x66,
0x66, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x72,
0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e,
0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
0x52, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73,
0x6b, 0x12, 0x58, 0x0a, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e,
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63,
0x52, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x73,
0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63,
0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f,
0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x65, 0x65,
0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22,
0x89, 0x07, 0x0a, 0x0b, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12,
0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e,
0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64,
0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02,
0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f,
0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74,
0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d,
0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a,
0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65,
0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a,
0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65,
0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a,
0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75,
0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c,
0x58, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63,
0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63,
0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73,
0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d,
0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67,
0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c,
0x58, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63,
0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63,
0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c,
0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74,
0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12,
0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59,
0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66,
0x66, 0x73, 0x65, 0x74, 0x59, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53,
0x69, 0x7a, 0x65, 0x58, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62,
0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f,
0x78, 0x53, 0x69, 0x7a, 0x65, 0x59, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69,
0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f,
0x77, 0x55, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55,
0x70, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28,
0x05, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c,
0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12,
0x1c, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x18, 0x15, 0x20, 0x01,
0x28, 0x05, 0x52, 0x09, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x12, 0x28, 0x0a,
0x0f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
0x18, 0x16, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, 0x6f,
0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x53, 0x74, 0x61,
0x74, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x6c, 0x53, 0x74, 0x61, 0x74,
0x65, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53,
0x74, 0x61, 0x74, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x66, 0x72, 0x61, 0x6d,
0x65, 0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0xc1, 0x08, 0x0a, 0x0e,
0x46, 0x69, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x38,
0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64,
0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65,
0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65,
0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69,
0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75,
0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73,
0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12,
0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c,
0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12,
0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c,
0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c,
0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53,
0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58,
0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b,
0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b,
0x56, 0x65, 0x6c, 0x59, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68,
0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61,
0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65,
0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58,
0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b,
0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b,
0x56, 0x65, 0x6c, 0x59, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66,
0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62,
0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24,
0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18,
0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66,
0x73, 0x65, 0x74, 0x59, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69,
0x7a, 0x65, 0x58, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f,
0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78,
0x53, 0x69, 0x7a, 0x65, 0x59, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74,
0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77,
0x55, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70,
0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05,
0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c, 0x6c,
0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1c,
0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28,
0x05, 0x52, 0x09, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f,
0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18,
0x16, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x73, 0x69, 0x6f, 0x6e,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x53, 0x74, 0x61, 0x74,
0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65,
0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53, 0x74,
0x61, 0x74, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65,
0x73, 0x49, 0x6e, 0x42, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x76, 0x69,
0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x18, 0xe7, 0x07, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x12,
0x23, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x18,
0xe8, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47,
0x72, 0x69, 0x64, 0x59, 0x12, 0x13, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x58, 0x18, 0xe9, 0x07, 0x20,
0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x69, 0x72, 0x58, 0x12, 0x13, 0x0a, 0x04, 0x64, 0x69, 0x72,
0x59, 0x18, 0xea, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x69, 0x72, 0x59, 0x12, 0x13,
0x0a, 0x04, 0x76, 0x65, 0x6c, 0x58, 0x18, 0xeb, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x76,
0x65, 0x6c, 0x58, 0x12, 0x13, 0x0a, 0x04, 0x76, 0x65, 0x6c, 0x59, 0x18, 0xec, 0x07, 0x20, 0x01,
0x28, 0x05, 0x52, 0x04, 0x76, 0x65, 0x6c, 0x59, 0x12, 0x15, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65,
0x64, 0x18, 0xed, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22,
0xc9, 0x05, 0x0a, 0x12, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64,
0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65,
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
0x54, 0x6f, 0x50, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x15,
0x77, 0x69, 0x6c, 0x6c, 0x4b, 0x69, 0x63, 0x6b, 0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69,
0x76, 0x65, 0x46, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x77, 0x69, 0x6c,
0x6c, 0x4b, 0x69, 0x63, 0x6b, 0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46,
0x6f, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49,
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f,
0x6f, 0x6d, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
0x03, 0x52, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x46, 0x0a, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54,
0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1e,
0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63,
0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x48,
0x0a, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64,
0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61, 0x73,
0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50,
0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x19, 0x72, 0x6f, 0x6c, 0x6c,
0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d,
0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x72, 0x6f, 0x6c,
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74,
0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12, 0x3a, 0x0a, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61,
0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e,
0x6f, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61,
0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e,
0x6f, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68,
0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x6e,
0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c,
0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0b, 0x20, 0x01,
0x28, 0x01, 0x52, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58,
0x12, 0x22, 0x0a, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59,
0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66,
0x73, 0x65, 0x74, 0x59, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f,
0x6e, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10,
0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x65, 0x70,
0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f,
0x6e, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x12, 0x39, 0x0a, 0x17, 0x66, 0x72, 0x61, 0x6d,
0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x64, 0x18, 0x80, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x66, 0x72, 0x61, 0x6d,
0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x64, 0x22, 0xc2, 0x03, 0x0a, 0x11, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e,
0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0a, 0x70, 0x6c, 0x61,
0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f, 0x77,
0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72,
0x72, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61,
0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x65, 0x6c,
0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75,
0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65,
0x74, 0x73, 0x12, 0x40, 0x0a, 0x0f, 0x66, 0x69, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75,
0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c,
0x6c, 0x65, 0x74, 0x52, 0x0f, 0x66, 0x69, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c,
0x6c, 0x65, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55,
0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x80,
0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55, 0x6e,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x2d, 0x0a,
0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79,
0x6e, 0x63, 0x18, 0x81, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c,
0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x25, 0x0a, 0x0d,
0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x82, 0x08,
0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c,
0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x14, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63,
0x61, 0x6c, 0x49, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x83, 0x08, 0x20, 0x01,
0x28, 0x05, 0x52, 0x14, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49,
0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74,
0x6c, 0x65, 0x5f, 0x73, 0x72, 0x76, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
0x12, 0x39, 0x0a, 0x17, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67,
0x67, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x80, 0x08, 0x20, 0x01,
0x28, 0x08, 0x52, 0x17, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67,
0x67, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xc2, 0x03, 0x0a, 0x11,
0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69,
0x64, 0x12, 0x36, 0x0a, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50,
0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x0a, 0x70,
0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f,
0x73, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74,
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x6d, 0x65,
0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x40, 0x0a, 0x0f, 0x66, 0x69,
0x72, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x72,
0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0f, 0x66, 0x69, 0x72,
0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x16,
0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d,
0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x80, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x62,
0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65,
0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x2d, 0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46,
0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x81, 0x08, 0x20, 0x01, 0x28,
0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65,
0x73, 0x79, 0x6e, 0x63, 0x12, 0x25, 0x0a, 0x0d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49,
0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x82, 0x08, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x70,
0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x14, 0x62,
0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x43, 0x6f, 0x75, 0x6e,
0x74, 0x65, 0x72, 0x18, 0x83, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x62, 0x75, 0x6c, 0x6c,
0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x5f, 0x73, 0x72, 0x76, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -46,6 +46,7 @@ func Serve(c *gin.Context) {
c.AbortWithStatus(http.StatusBadRequest)
return
}
boundRoomId := 0
expectedRoomId := 0
var err error
@@ -395,3 +396,89 @@ func Serve(c *gin.Context) {
startOrFeedHeartbeatWatchdog(conn)
go receivingLoopAgainstPlayer()
}
func HandleSecondaryWsSessionForPlayer(c *gin.Context) {
token, ok := c.GetQuery("intAuthToken")
if !ok {
Logger.Warn("Secondary ws session req must have intAuthToken param!")
c.AbortWithStatus(http.StatusBadRequest)
return
}
boundRoomId := 0
var err error = nil
if boundRoomIdStr, hasBoundRoomId := c.GetQuery("boundRoomId"); hasBoundRoomId {
boundRoomId, err = strconv.Atoi(boundRoomIdStr)
if err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
} else {
Logger.Warn("Secondary ws session req must have boundRoomId param:", zap.Any("intAuthToken", token))
c.AbortWithStatus(http.StatusBadRequest)
return
}
var pRoom *models.Room = nil
// Deliberately querying playerId after querying room, because the former is against persistent storage and could be slow!
if tmpPRoom, existent := (*models.RoomMapManagerIns)[int32(boundRoomId)]; !existent {
Logger.Warn("Secondary ws session failed to get:\n", zap.Any("intAuthToken", token), zap.Any("forBoundRoomId", boundRoomId))
c.AbortWithStatus(http.StatusBadRequest)
} else {
pRoom = tmpPRoom
}
// TODO: Wrap the following 2 stmts by sql transaction!
playerId, err := models.GetPlayerIdByToken(token)
if err != nil || playerId == 0 {
// TODO: Abort with specific message.
Logger.Warn("Secondary ws session playerLogin record not found for ws authentication:", zap.Any("intAuthToken", token))
c.AbortWithStatus(http.StatusBadRequest)
return
}
Logger.Info("Secondary ws session playerLogin record has been found for ws authentication:", zap.Any("playerId", playerId), zap.Any("intAuthToken", token), zap.Any("boundRoomId", boundRoomId))
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
Logger.Error("Secondary ws session upgrade:", zap.Error(err), zap.Any("playerId", playerId))
c.AbortWithStatus(http.StatusBadRequest)
return
}
connHasBeenSignaledToClose := int32(0)
pConnHasBeenSignaledToClose := &connHasBeenSignaledToClose
signalToCloseConnOfThisPlayer := func(customRetCode int, customRetMsg string) {
if swapped := atomic.CompareAndSwapInt32(pConnHasBeenSignaledToClose, 0, 1); !swapped {
return
}
Logger.Warn("Secondary ws session signalToCloseConnOfThisPlayer:", zap.Any("playerId", playerId), zap.Any("customRetCode", customRetCode), zap.Any("customRetMsg", customRetMsg))
defer func() {
if r := recover(); r != nil {
Logger.Error("Secondary ws session recovered from: ", zap.Any("panic", r))
}
}()
closeMessage := websocket.FormatCloseMessage(customRetCode, customRetMsg)
err := conn.WriteControl(websocket.CloseMessage, closeMessage, time.Now().Add(time.Millisecond*(ConstVals.Ws.WillKickIfInactiveFor)))
if err != nil {
Logger.Error("Secondary ws session unable to send the CloseFrame control message to player(client-side):", zap.Any("playerId", playerId), zap.Error(err))
}
time.AfterFunc(3*time.Second, func() {
// To actually terminates the underlying TCP connection which might be in `CLOSE_WAIT` state if inspected by `netstat`.
conn.Close()
})
}
onReceivedCloseMessageFromClient := func(code int, text string) error {
Logger.Warn("Secondary ws session triggered `onReceivedCloseMessageFromClient`:", zap.Any("code", code), zap.Any("playerId", playerId), zap.Any("message", text))
signalToCloseConnOfThisPlayer(code, text)
return nil
}
conn.SetCloseHandler(onReceivedCloseMessageFromClient)
pRoom.SetSecondarySession(int32(playerId), conn, signalToCloseConnOfThisPlayer)
}

File diff suppressed because one or more lines are too long

View File

@@ -18,61 +18,43 @@
}
},
{
"frame": 0.06666666666666667,
"frame": 0.05,
"value": {
"__uuid__": "dd9a00aa-ddbc-4b01-a7cb-3c43c3a655b6"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "f66e83bd-1afc-4957-bb16-488d70566ed1"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "bd682c41-dc62-49ff-a96a-18b33e50a6de"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "94ccab85-e32f-4e13-b0e5-72c798f78ad1"
}
},
{
"frame": 0.3,
"frame": 0.08333333333333333,
"value": {
"__uuid__": "e80d3a01-5048-42b7-a280-cb6aa01602c2"
}
},
{
"frame": 0.36666666666666664,
"frame": 0.11666666666666667,
"value": {
"__uuid__": "d899088c-be62-47b4-9ebf-0a89a2261565"
}
},
{
"frame": 0.4166666666666667,
"frame": 0.15,
"value": {
"__uuid__": "5b1e5aa7-fd82-47ae-a5b2-6d4983d848ed"
}
},
{
"frame": 0.48333333333333334,
"frame": 0.18333333333333332,
"value": {
"__uuid__": "c2945988-b4bb-4583-a5ef-2fa02b23a347"
}
},
{
"frame": 0.5666666666666667,
"frame": 0.23333333333333334,
"value": {
"__uuid__": "070ea1e3-9c07-4735-8b94-515ef70216ad"
}
},
{
"frame": 0.6666666666666666,
"frame": 0.2833333333333333,
"value": {
"__uuid__": "3b8bc5c0-26df-4218-b7dc-134a36080a35"
}

View File

@@ -15,7 +15,7 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{806,750},{112,128}}</string>
<string>{{384,989},{112,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -30,7 +30,7 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{0,1076},{112,128}}</string>
<string>{{256,990},{112,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -60,7 +60,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{528,515},{80,128}}</string>
<string>{{940,0},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -75,7 +75,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{934,640},{80,128}}</string>
<string>{{940,128},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -90,7 +90,7 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{128,1076},{112,128}}</string>
<string>{{128,1082},{112,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -105,7 +105,7 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{678,862},{112,128}}</string>
<string>{{0,1188},{112,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -150,7 +150,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{934,768},{80,128}}</string>
<string>{{940,256},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -165,7 +165,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{934,896},{80,128}}</string>
<string>{{937,384},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -180,9 +180,9 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{806,958},{80,128}}</string>
<string>{{528,515},{80,128}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Atk2_0.png</key>
<dict>
@@ -195,7 +195,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{934,1024},{80,128}}</string>
<string>{{936,512},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -225,7 +225,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{128,964},{128,112}}</string>
<string>{{0,1076},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -240,7 +240,7 @@
<key>spriteSourceSize</key>
<string>{96,96}</string>
<key>textureRect</key>
<string>{{912,1152},{96,96}}</string>
<string>{{688,1357},{96,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -255,7 +255,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{340,1197},{96,112}}</string>
<string>{{240,1360},{96,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -270,7 +270,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{452,1196},{96,112}}</string>
<string>{{352,1358},{96,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -285,7 +285,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{564,1155},{96,112}}</string>
<string>{{920,1072},{96,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -300,7 +300,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{608,1043},{96,112}}</string>
<string>{{914,1184},{96,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -330,7 +330,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{678,750},{128,112}}</string>
<string>{{806,631},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -540,7 +540,7 @@
<key>spriteSourceSize</key>
<string>{112,112}</string>
<key>textureRect</key>
<string>{{448,1293},{112,112}}</string>
<string>{{802,1149},{112,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -555,9 +555,9 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{660,1155},{96,112}}</string>
<string>{{800,1261},{96,112}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atked1_3.png</key>
<dict>
@@ -570,7 +570,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{384,988},{128,112}}</string>
<string>{{806,743},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -645,7 +645,7 @@
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{0,1188},{114,112}}</string>
<string>{{806,1037},{114,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -660,9 +660,9 @@
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{114,1188},{114,112}}</string>
<string>{{384,1213},{114,112}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Dashing_3.png</key>
<dict>
@@ -675,7 +675,7 @@
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{0,1300},{114,112}}</string>
<string>{{464,1327},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -690,7 +690,7 @@
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{112,1300},{114,112}}</string>
<string>{{496,1213},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -705,7 +705,7 @@
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{0,1300},{114,112}}</string>
<string>{{464,1327},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -720,7 +720,7 @@
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{224,1300},{114,112}}</string>
<string>{{576,1327},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -735,56 +735,11 @@
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{336,1293},{114,112}}</string>
<string>{{688,1043},{114,112}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>GetUp1_1.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{128,118}</string>
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{384,634},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_2.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{128,118}</string>
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{384,752},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_3.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{128,118}</string>
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{256,753},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_4.png</key>
<dict>
<key>aliases</key>
<array/>
@@ -799,7 +754,7 @@
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_5.png</key>
<key>GetUp1_2.png</key>
<dict>
<key>aliases</key>
<array/>
@@ -814,6 +769,51 @@
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_3.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{128,118}</string>
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{384,753},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_4.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{128,118}</string>
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{678,631},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_5.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{128,118}</string>
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{384,871},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>GetUp1_6.png</key>
<dict>
<key>aliases</key>
@@ -825,7 +825,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{384,870},{128,118}}</string>
<string>{{256,872},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -840,7 +840,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{256,871},{128,118}}</string>
<string>{{128,964},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -855,7 +855,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{940,0},{70,128}}</string>
<string>{{608,531},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -870,7 +870,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{940,128},{70,128}}</string>
<string>{{608,659},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -885,7 +885,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{940,256},{70,128}}</string>
<string>{{608,787},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -900,7 +900,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{937,384},{70,128}}</string>
<string>{{608,915},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -915,9 +915,9 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{936,512},{70,128}}</string>
<string>{{128,1290},{70,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Idle1_14.png</key>
<dict>
@@ -930,9 +930,9 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{608,531},{70,128}}</string>
<string>{{0,1300},{70,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Idle1_15.png</key>
<dict>
@@ -945,9 +945,9 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{608,659},{70,128}}</string>
<string>{{0,1370},{70,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Idle1_2.png</key>
<dict>
@@ -960,9 +960,9 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{608,659},{70,128}}</string>
<string>{{0,1370},{70,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Idle1_3.png</key>
<dict>
@@ -975,9 +975,9 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{608,531},{70,128}}</string>
<string>{{0,1300},{70,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Idle1_4.png</key>
<dict>
@@ -990,71 +990,11 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{936,512},{70,128}}</string>
<string>{{128,1290},{70,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Idle1_5.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{937,384},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Idle1_6.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{940,256},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Idle1_7.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{940,128},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Idle1_8.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{608,787},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Idle1_9.png</key>
<dict>
<key>aliases</key>
<array/>
@@ -1069,6 +1009,66 @@
<key>textureRotated</key>
<false/>
</dict>
<key>Idle1_6.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{608,787},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Idle1_7.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{608,659},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Idle1_8.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{806,967},{70,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>Idle1_9.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{70,128}</string>
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{678,973},{70,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>InAirAtk1_0.png</key>
<dict>
<key>aliases</key>
@@ -1080,7 +1080,7 @@
<key>spriteSourceSize</key>
<string>{112,96}</string>
<key>textureRect</key>
<string>{{228,1197},{112,96}}</string>
<string>{{128,1360},{112,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1125,7 +1125,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{256,989},{128,112}}</string>
<string>{{678,749},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1140,7 +1140,7 @@
<key>spriteSourceSize</key>
<string>{96,96}</string>
<key>textureRect</key>
<string>{{672,1363},{96,96}}</string>
<string>{{784,1357},{96,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1155,7 +1155,7 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{672,1267},{80,96}}</string>
<string>{{934,976},{80,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1170,7 +1170,7 @@
<key>spriteSourceSize</key>
<string>{112,112}</string>
<key>textureRect</key>
<string>{{560,1292},{112,112}}</string>
<string>{{688,1155},{112,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1185,7 +1185,7 @@
<key>spriteSourceSize</key>
<string>{128,96}</string>
<key>textureRect</key>
<string>{{384,1100},{128,96}}</string>
<string>{{256,1102},{128,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1200,9 +1200,9 @@
<key>spriteSourceSize</key>
<string>{80,112}</string>
<key>textureRect</key>
<string>{{800,1038},{80,112}}</string>
<string>{{934,640},{80,112}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirIdle1_1.png</key>
<dict>
@@ -1215,9 +1215,9 @@
<key>spriteSourceSize</key>
<string>{80,112}</string>
<key>textureRect</key>
<string>{{800,1118},{80,112}}</string>
<string>{{934,752},{80,112}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirIdle1_2.png</key>
<dict>
@@ -1230,7 +1230,7 @@
<key>spriteSourceSize</key>
<string>{64,128}</string>
<key>textureRect</key>
<string>{{678,974},{64,128}}</string>
<string>{{256,1294},{64,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1245,9 +1245,9 @@
<key>spriteSourceSize</key>
<string>{80,112}</string>
<key>textureRect</key>
<string>{{756,1198},{80,112}}</string>
<string>{{934,864},{80,112}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirIdle1_4.png</key>
<dict>
@@ -1260,9 +1260,9 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{752,1278},{80,96}}</string>
<string>{{608,1043},{80,96}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirIdle1_5.png</key>
<dict>
@@ -1275,7 +1275,7 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{768,1358},{80,96}}</string>
<string>{{608,1139},{80,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1290,7 +1290,7 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{868,1248},{80,96}}</string>
<string>{{688,1267},{80,96}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1305,9 +1305,9 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{704,1038},{96,112}}</string>
<string>{{912,1296},{96,112}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_8.png</key>
<dict>
@@ -1320,7 +1320,7 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{256,1101},{96,128}}</string>
<string>{{128,1194},{96,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1335,7 +1335,7 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{806,862},{96,128}}</string>
<string>{{256,1198},{96,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1414,6 +1414,51 @@
<key>textureRotated</key>
<true/>
</dict>
<key>TurnAround1_1.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{112,128}</string>
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{806,855},{112,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>TurnAround1_2.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{112,128}</string>
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{678,861},{112,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>TurnAround1_3.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{112,128}</string>
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{384,1101},{112,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>Walking_1.png</key>
<dict>
<key>aliases</key>
@@ -1455,7 +1500,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{680,512},{119,128}}</string>
<string>{{272,515},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1470,7 +1515,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{808,512},{119,128}}</string>
<string>{{128,608},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1485,7 +1530,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{272,515},{119,128}}</string>
<string>{{0,720},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1500,7 +1545,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{128,608},{119,128}}</string>
<string>{{400,515},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1515,7 +1560,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{0,720},{119,128}}</string>
<string>{{256,634},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1530,7 +1575,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{400,515},{119,128}}</string>
<string>{{128,727},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1545,7 +1590,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{678,631},{119,128}}</string>
<string>{{0,839},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1560,7 +1605,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{806,631},{119,128}}</string>
<string>{{384,634},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1575,7 +1620,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{256,634},{119,128}}</string>
<string>{{680,512},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1590,7 +1635,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{128,727},{119,128}}</string>
<string>{{808,512},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1605,7 +1650,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{0,839},{119,128}}</string>
<string>{{256,753},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1621,9 +1666,9 @@
<key>realTextureFileName</key>
<string>KnifeGirl.png</string>
<key>size</key>
<string>{1014,1459}</string>
<string>{1024,1456}</string>
<key>smartupdate</key>
<string>$TexturePacker:SmartUpdate:4ca72309f7dc04bba6be361462471d91:9a48d10caa37a76ff8c43fb72bce6103:1ae107e0c6667a1ecb5ed98687517e0e$</string>
<string>$TexturePacker:SmartUpdate:8fd7507b5e24a1de6da5e4a6c568fcd3:d861e924a13180a640774a9c85662e57:1ae107e0c6667a1ecb5ed98687517e0e$</string>
<key>textureFileName</key>
<string>KnifeGirl.png</string>
</dict>

View File

@@ -3,8 +3,8 @@
"uuid": "579bc0c1-f5e2-4a5d-889b-9d567e53b0e6",
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"size": {
"width": 1014,
"height": 1459
"width": 1024,
"height": 1456
},
"type": "Texture Packer",
"subMetas": {
@@ -17,8 +17,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 806,
"trimY": 750,
"trimX": 384,
"trimY": 989,
"width": 112,
"height": 128,
"rawWidth": 112,
@@ -39,8 +39,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 1076,
"trimX": 256,
"trimY": 990,
"width": 112,
"height": 128,
"rawWidth": 112,
@@ -83,8 +83,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 528,
"trimY": 515,
"trimX": 940,
"trimY": 0,
"width": 80,
"height": 128,
"rawWidth": 80,
@@ -105,8 +105,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 934,
"trimY": 640,
"trimX": 940,
"trimY": 128,
"width": 80,
"height": 128,
"rawWidth": 80,
@@ -128,7 +128,7 @@
"offsetX": 0,
"offsetY": 0,
"trimX": 128,
"trimY": 1076,
"trimY": 1082,
"width": 112,
"height": 128,
"rawWidth": 112,
@@ -149,8 +149,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 678,
"trimY": 862,
"trimX": 0,
"trimY": 1188,
"width": 112,
"height": 128,
"rawWidth": 112,
@@ -215,8 +215,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 934,
"trimY": 768,
"trimX": 940,
"trimY": 256,
"width": 80,
"height": 128,
"rawWidth": 80,
@@ -237,8 +237,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 934,
"trimY": 896,
"trimX": 937,
"trimY": 384,
"width": 80,
"height": 128,
"rawWidth": 80,
@@ -256,11 +256,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 806,
"trimY": 958,
"trimX": 528,
"trimY": 515,
"width": 80,
"height": 128,
"rawWidth": 80,
@@ -281,8 +281,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 934,
"trimY": 1024,
"trimX": 936,
"trimY": 512,
"width": 80,
"height": 128,
"rawWidth": 80,
@@ -325,8 +325,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 128,
"trimY": 964,
"trimX": 0,
"trimY": 1076,
"width": 128,
"height": 112,
"rawWidth": 128,
@@ -347,8 +347,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 912,
"trimY": 1152,
"trimX": 688,
"trimY": 1357,
"width": 96,
"height": 96,
"rawWidth": 96,
@@ -369,8 +369,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 340,
"trimY": 1197,
"trimX": 240,
"trimY": 1360,
"width": 96,
"height": 112,
"rawWidth": 96,
@@ -391,8 +391,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 452,
"trimY": 1196,
"trimX": 352,
"trimY": 1358,
"width": 96,
"height": 112,
"rawWidth": 96,
@@ -413,8 +413,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 564,
"trimY": 1155,
"trimX": 920,
"trimY": 1072,
"width": 96,
"height": 112,
"rawWidth": 96,
@@ -435,8 +435,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 608,
"trimY": 1043,
"trimX": 914,
"trimY": 1184,
"width": 96,
"height": 112,
"rawWidth": 96,
@@ -479,8 +479,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 678,
"trimY": 750,
"trimX": 806,
"trimY": 631,
"width": 128,
"height": 112,
"rawWidth": 128,
@@ -787,8 +787,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 448,
"trimY": 1293,
"trimX": 802,
"trimY": 1149,
"width": 112,
"height": 112,
"rawWidth": 112,
@@ -806,11 +806,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 660,
"trimY": 1155,
"trimX": 800,
"trimY": 1261,
"width": 96,
"height": 112,
"rawWidth": 96,
@@ -831,8 +831,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 384,
"trimY": 988,
"trimX": 806,
"trimY": 743,
"width": 128,
"height": 112,
"rawWidth": 128,
@@ -941,8 +941,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 1188,
"trimX": 806,
"trimY": 1037,
"width": 114,
"height": 112,
"rawWidth": 114,
@@ -960,11 +960,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 114,
"trimY": 1188,
"trimX": 384,
"trimY": 1213,
"width": 114,
"height": 112,
"rawWidth": 114,
@@ -985,8 +985,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 1300,
"trimX": 464,
"trimY": 1327,
"width": 114,
"height": 112,
"rawWidth": 114,
@@ -1007,8 +1007,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 112,
"trimY": 1300,
"trimX": 496,
"trimY": 1213,
"width": 114,
"height": 112,
"rawWidth": 114,
@@ -1029,8 +1029,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 1300,
"trimX": 464,
"trimY": 1327,
"width": 114,
"height": 112,
"rawWidth": 114,
@@ -1051,8 +1051,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 224,
"trimY": 1300,
"trimX": 576,
"trimY": 1327,
"width": 114,
"height": 112,
"rawWidth": 114,
@@ -1070,11 +1070,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 336,
"trimY": 1293,
"trimX": 688,
"trimY": 1043,
"width": 114,
"height": 112,
"rawWidth": 114,
@@ -1095,8 +1095,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 384,
"trimY": 634,
"trimX": 128,
"trimY": 846,
"width": 128,
"height": 118,
"rawWidth": 128,
@@ -1117,8 +1117,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 384,
"trimY": 752,
"trimX": 0,
"trimY": 958,
"width": 128,
"height": 118,
"rawWidth": 128,
@@ -1139,7 +1139,7 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 256,
"trimX": 384,
"trimY": 753,
"width": 128,
"height": 118,
@@ -1161,8 +1161,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 128,
"trimY": 846,
"trimX": 678,
"trimY": 631,
"width": 128,
"height": 118,
"rawWidth": 128,
@@ -1183,8 +1183,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 958,
"trimX": 384,
"trimY": 871,
"width": 128,
"height": 118,
"rawWidth": 128,
@@ -1205,8 +1205,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 384,
"trimY": 870,
"trimX": 256,
"trimY": 872,
"width": 128,
"height": 118,
"rawWidth": 128,
@@ -1227,8 +1227,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 256,
"trimY": 871,
"trimX": 128,
"trimY": 964,
"width": 128,
"height": 118,
"rawWidth": 128,
@@ -1249,8 +1249,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 940,
"trimY": 0,
"trimX": 608,
"trimY": 531,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1271,8 +1271,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 940,
"trimY": 128,
"trimX": 608,
"trimY": 659,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1293,8 +1293,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 940,
"trimY": 256,
"trimX": 608,
"trimY": 787,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1315,8 +1315,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 937,
"trimY": 384,
"trimX": 608,
"trimY": 915,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1334,11 +1334,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 936,
"trimY": 512,
"trimX": 128,
"trimY": 1290,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1356,11 +1356,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 608,
"trimY": 531,
"trimX": 0,
"trimY": 1300,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1378,11 +1378,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 608,
"trimY": 659,
"trimX": 0,
"trimY": 1370,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1400,11 +1400,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 608,
"trimY": 659,
"trimX": 0,
"trimY": 1370,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1422,11 +1422,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 608,
"trimY": 531,
"trimX": 0,
"trimY": 1300,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1444,11 +1444,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 936,
"trimY": 512,
"trimX": 128,
"trimY": 1290,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1469,8 +1469,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 937,
"trimY": 384,
"trimX": 608,
"trimY": 915,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1491,8 +1491,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 940,
"trimY": 256,
"trimX": 608,
"trimY": 787,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1513,8 +1513,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 940,
"trimY": 128,
"trimX": 608,
"trimY": 659,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1532,11 +1532,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 608,
"trimY": 787,
"trimX": 806,
"trimY": 967,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1554,11 +1554,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 608,
"trimY": 915,
"trimX": 678,
"trimY": 973,
"width": 70,
"height": 128,
"rawWidth": 70,
@@ -1579,8 +1579,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 228,
"trimY": 1197,
"trimX": 128,
"trimY": 1360,
"width": 112,
"height": 96,
"rawWidth": 112,
@@ -1645,8 +1645,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 256,
"trimY": 989,
"trimX": 678,
"trimY": 749,
"width": 128,
"height": 112,
"rawWidth": 128,
@@ -1667,8 +1667,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 672,
"trimY": 1363,
"trimX": 784,
"trimY": 1357,
"width": 96,
"height": 96,
"rawWidth": 96,
@@ -1689,8 +1689,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 672,
"trimY": 1267,
"trimX": 934,
"trimY": 976,
"width": 80,
"height": 96,
"rawWidth": 80,
@@ -1711,8 +1711,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 560,
"trimY": 1292,
"trimX": 688,
"trimY": 1155,
"width": 112,
"height": 112,
"rawWidth": 112,
@@ -1733,8 +1733,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 384,
"trimY": 1100,
"trimX": 256,
"trimY": 1102,
"width": 128,
"height": 96,
"rawWidth": 128,
@@ -1752,11 +1752,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 800,
"trimY": 1038,
"trimX": 934,
"trimY": 640,
"width": 80,
"height": 112,
"rawWidth": 80,
@@ -1774,11 +1774,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 800,
"trimY": 1118,
"trimX": 934,
"trimY": 752,
"width": 80,
"height": 112,
"rawWidth": 80,
@@ -1799,8 +1799,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 678,
"trimY": 974,
"trimX": 256,
"trimY": 1294,
"width": 64,
"height": 128,
"rawWidth": 64,
@@ -1818,11 +1818,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 756,
"trimY": 1198,
"trimX": 934,
"trimY": 864,
"width": 80,
"height": 112,
"rawWidth": 80,
@@ -1840,11 +1840,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 752,
"trimY": 1278,
"trimX": 608,
"trimY": 1043,
"width": 80,
"height": 96,
"rawWidth": 80,
@@ -1865,8 +1865,8 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 768,
"trimY": 1358,
"trimX": 608,
"trimY": 1139,
"width": 80,
"height": 96,
"rawWidth": 80,
@@ -1887,8 +1887,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 868,
"trimY": 1248,
"trimX": 688,
"trimY": 1267,
"width": 80,
"height": 96,
"rawWidth": 80,
@@ -1906,11 +1906,11 @@
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 704,
"trimY": 1038,
"trimX": 912,
"trimY": 1296,
"width": 96,
"height": 112,
"rawWidth": 96,
@@ -1931,8 +1931,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 256,
"trimY": 1101,
"trimX": 128,
"trimY": 1194,
"width": 96,
"height": 128,
"rawWidth": 96,
@@ -1953,8 +1953,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 806,
"trimY": 862,
"trimX": 256,
"trimY": 1198,
"width": 96,
"height": 128,
"rawWidth": 96,
@@ -2076,6 +2076,72 @@
"spriteType": "normal",
"subMetas": {}
},
"TurnAround1_1.png": {
"ver": "1.0.4",
"uuid": "28ee1f29-e538-4d36-bb5c-275f9e3b392b",
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 806,
"trimY": 855,
"width": 112,
"height": 128,
"rawWidth": 112,
"rawHeight": 128,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"spriteType": "normal",
"subMetas": {}
},
"TurnAround1_2.png": {
"ver": "1.0.4",
"uuid": "211a73bb-31d7-4e6c-901e-f6939d9214e0",
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 678,
"trimY": 861,
"width": 112,
"height": 128,
"rawWidth": 112,
"rawHeight": 128,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"spriteType": "normal",
"subMetas": {}
},
"TurnAround1_3.png": {
"ver": "1.0.4",
"uuid": "048c41dc-fc00-4bc4-8041-6003e7c2b6e4",
"rawTextureUuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 384,
"trimY": 1101,
"width": 112,
"height": 128,
"rawWidth": 112,
"rawHeight": 128,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"spriteType": "normal",
"subMetas": {}
},
"Walking_1.png": {
"ver": "1.0.4",
"uuid": "9435195e-4560-495e-b1ae-083c0c87e8a0",
@@ -2129,8 +2195,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 680,
"trimY": 512,
"trimX": 272,
"trimY": 515,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2151,8 +2217,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 808,
"trimY": 512,
"trimX": 128,
"trimY": 608,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2173,8 +2239,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 272,
"trimY": 515,
"trimX": 0,
"trimY": 720,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2195,8 +2261,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 128,
"trimY": 608,
"trimX": 400,
"trimY": 515,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2217,8 +2283,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 720,
"trimX": 256,
"trimY": 634,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2239,8 +2305,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 400,
"trimY": 515,
"trimX": 128,
"trimY": 727,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2261,8 +2327,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 678,
"trimY": 631,
"trimX": 0,
"trimY": 839,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2283,8 +2349,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 806,
"trimY": 631,
"trimX": 384,
"trimY": 634,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2305,8 +2371,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 256,
"trimY": 634,
"trimX": 680,
"trimY": 512,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2327,8 +2393,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 128,
"trimY": 727,
"trimX": 808,
"trimY": 512,
"width": 119,
"height": 128,
"rawWidth": 119,
@@ -2349,8 +2415,8 @@
"rotated": true,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 839,
"trimX": 256,
"trimY": 753,
"width": 119,
"height": 128,
"rawWidth": 119,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 119 KiB

View File

@@ -3,7 +3,7 @@
"_name": "Walking",
"_objFlags": 0,
"_native": "",
"_duration": 1.5166666666666666,
"_duration": 0.6333333333333333,
"sample": 60,
"speed": 1.2,
"wrapMode": 2,
@@ -13,78 +13,78 @@
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "c3b14ecc-a6d9-4cb3-8637-ca7b407a0f5c"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "9435195e-4560-495e-b1ae-083c0c87e8a0"
}
},
{
"frame": 0.18333333333333332,
"frame": 0.06666666666666667,
"value": {
"__uuid__": "ec048360-7a17-4f22-ba52-eb86ec1acae8"
}
},
{
"frame": 0.2833333333333333,
"frame": 0.11666666666666667,
"value": {
"__uuid__": "82bb81e3-667c-4280-8710-211f4904ef2f"
}
},
{
"frame": 0.4,
"frame": 0.16666666666666666,
"value": {
"__uuid__": "c3b14ecc-a6d9-4cb3-8637-ca7b407a0f5c"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "f958fb7f-ef5a-4918-81f3-564004572f45"
}
},
{
"frame": 0.5333333333333333,
"frame": 0.26666666666666666,
"value": {
"__uuid__": "8a0ecf92-db26-4206-9a80-20e749055def"
}
},
{
"frame": 0.65,
"frame": 0.31666666666666665,
"value": {
"__uuid__": "942f2e02-a700-4fbf-877e-08c93e4d4010"
}
},
{
"frame": 0.7666666666666667,
"frame": 0.36666666666666664,
"value": {
"__uuid__": "30546064-1a11-499e-8523-a82c83951c73"
}
},
{
"frame": 0.9,
"frame": 0.4166666666666667,
"value": {
"__uuid__": "515bb75f-7a1f-4500-8aa9-c895915ce19f"
}
},
{
"frame": 1.0333333333333334,
"frame": 0.4666666666666667,
"value": {
"__uuid__": "9100da6b-7582-4afb-9698-3d67d3b2012d"
}
},
{
"frame": 1.2166666666666666,
"frame": 0.5166666666666667,
"value": {
"__uuid__": "1257f72d-0cb3-4750-ae70-13c2d8eb2269"
}
},
{
"frame": 1.3833333333333333,
"frame": 0.5666666666666667,
"value": {
"__uuid__": "1d34b6db-27ba-4e26-864d-0f00d501765e"
}
},
{
"frame": 1.5,
"frame": 0.6166666666666667,
"value": {
"__uuid__": "c317a75a-52c0-4c38-9300-a064cbf4efb3"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

After

Width:  |  Height:  |  Size: 269 KiB

View File

@@ -15,7 +15,7 @@
<key>spriteSourceSize</key>
<string>{62,92}</string>
<key>textureRect</key>
<string>{{1277,188},{62,92}}</string>
<string>{{1307,188},{62,92}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -30,7 +30,7 @@
<key>spriteSourceSize</key>
<string>{77,99}</string>
<key>textureRect</key>
<string>{{748,0},{77,99}}</string>
<string>{{782,101},{77,99}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -45,7 +45,7 @@
<key>spriteSourceSize</key>
<string>{112,99}</string>
<key>textureRect</key>
<string>{{408,348},{112,99}}</string>
<string>{{381,360},{112,99}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -60,7 +60,7 @@
<key>spriteSourceSize</key>
<string>{96,100}</string>
<key>textureRect</key>
<string>{{664,315},{96,100}}</string>
<string>{{704,312},{96,100}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -75,7 +75,7 @@
<key>spriteSourceSize</key>
<string>{62,92}</string>
<key>textureRect</key>
<string>{{1277,188},{62,92}}</string>
<string>{{1307,188},{62,92}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -90,7 +90,7 @@
<key>spriteSourceSize</key>
<string>{58,97}</string>
<key>textureRect</key>
<string>{{1023,194},{58,97}}</string>
<string>{{983,388},{58,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -105,9 +105,9 @@
<key>spriteSourceSize</key>
<string>{60,90}</string>
<key>textureRect</key>
<string>{{1393,141},{60,90}}</string>
<string>{{1424,0},{60,90}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Atk2_2.png</key>
<dict>
@@ -120,7 +120,7 @@
<key>spriteSourceSize</key>
<string>{84,96}</string>
<key>textureRect</key>
<string>{{1087,97},{84,96}}</string>
<string>{{1082,291},{84,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -135,7 +135,7 @@
<key>spriteSourceSize</key>
<string>{55,100}</string>
<key>textureRect</key>
<string>{{731,101},{55,100}}</string>
<string>{{738,206},{55,100}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -150,9 +150,9 @@
<key>spriteSourceSize</key>
<string>{63,100}</string>
<key>textureRect</key>
<string>{{717,206},{63,100}}</string>
<string>{{0,437},{63,100}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atk2_5.png</key>
<dict>
@@ -165,7 +165,7 @@
<key>spriteSourceSize</key>
<string>{66,101}</string>
<key>textureRect</key>
<string>{{682,0},{66,101}}</string>
<string>{{755,0},{66,101}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -180,7 +180,7 @@
<key>spriteSourceSize</key>
<string>{80,95}</string>
<key>textureRect</key>
<string>{{1126,0},{80,95}}</string>
<string>{{1099,387},{80,95}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -195,7 +195,7 @@
<key>spriteSourceSize</key>
<string>{116,109}</string>
<key>textureRect</key>
<string>{{315,119},{116,109}}</string>
<string>{{336,244},{116,109}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -210,7 +210,7 @@
<key>spriteSourceSize</key>
<string>{102,96}</string>
<key>textureRect</key>
<string>{{621,213},{102,96}}</string>
<string>{{608,325},{102,96}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -225,9 +225,9 @@
<key>spriteSourceSize</key>
<string>{75,102}</string>
<key>textureRect</key>
<string>{{139,421},{75,102}}</string>
<string>{{663,210},{75,102}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Atk3_0.png</key>
<dict>
@@ -240,7 +240,7 @@
<key>spriteSourceSize</key>
<string>{66,109}</string>
<key>textureRect</key>
<string>{{469,110},{66,109}}</string>
<string>{{480,339},{66,109}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -255,7 +255,7 @@
<key>spriteSourceSize</key>
<string>{66,113}</string>
<key>textureRect</key>
<string>{{355,235},{66,113}}</string>
<string>{{403,114},{66,113}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -330,7 +330,7 @@
<key>spriteSourceSize</key>
<string>{78,131}</string>
<key>textureRect</key>
<string>{{137,290},{78,131}}</string>
<string>{{78,0},{78,131}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -345,9 +345,9 @@
<key>spriteSourceSize</key>
<string>{59,139}</string>
<key>textureRect</key>
<string>{{0,437},{59,139}}</string>
<string>{{78,290},{59,139}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Atk3_8.png</key>
<dict>
@@ -360,7 +360,7 @@
<key>spriteSourceSize</key>
<string>{59,139}</string>
<key>textureRect</key>
<string>{{78,290},{59,139}}</string>
<string>{{137,290},{59,139}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -375,9 +375,9 @@
<key>spriteSourceSize</key>
<string>{62,97}</string>
<key>textureRect</key>
<string>{{507,434},{62,97}}</string>
<string>{{962,291},{62,97}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Atked1_1.png</key>
<dict>
@@ -390,9 +390,9 @@
<key>spriteSourceSize</key>
<string>{73,95}</string>
<key>textureRect</key>
<string>{{1171,95},{73,95}}</string>
<string>{{641,427},{73,95}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atked1_2.png</key>
<dict>
@@ -405,7 +405,7 @@
<key>spriteSourceSize</key>
<string>{90,89}</string>
<key>textureRect</key>
<string>{{1324,0},{90,89}}</string>
<string>{{1335,0},{90,89}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -420,7 +420,7 @@
<key>spriteSourceSize</key>
<string>{95,80}</string>
<key>textureRect</key>
<string>{{1084,291},{95,80}}</string>
<string>{{1168,193},{95,80}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -435,7 +435,7 @@
<key>spriteSourceSize</key>
<string>{80,95}</string>
<key>textureRect</key>
<string>{{1010,388},{80,95}}</string>
<string>{{1166,290},{80,95}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -450,7 +450,7 @@
<key>spriteSourceSize</key>
<string>{83,92}</string>
<key>textureRect</key>
<string>{{1208,382},{83,92}}</string>
<string>{{1299,382},{83,92}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -465,7 +465,7 @@
<key>spriteSourceSize</key>
<string>{92,83}</string>
<key>textureRect</key>
<string>{{1224,284},{92,83}}</string>
<string>{{1306,284},{92,83}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -480,7 +480,7 @@
<key>spriteSourceSize</key>
<string>{112,45}</string>
<key>textureRect</key>
<string>{{424,115},{112,45}}</string>
<string>{{469,112},{112,45}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -495,7 +495,7 @@
<key>spriteSourceSize</key>
<string>{88,69}</string>
<key>textureRect</key>
<string>{{604,427},{88,69}}</string>
<string>{{1443,222},{88,69}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -510,7 +510,7 @@
<key>spriteSourceSize</key>
<string>{91,90}</string>
<key>textureRect</key>
<string>{{1303,93},{91,90}}</string>
<string>{{1313,93},{91,90}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -525,7 +525,7 @@
<key>spriteSourceSize</key>
<string>{120,93}</string>
<key>textureRect</key>
<string>{{222,123},{120,93}}</string>
<string>{{254,124},{120,93}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -540,9 +540,9 @@
<key>spriteSourceSize</key>
<string>{100,112}</string>
<key>textureRect</key>
<string>{{241,396},{100,112}}</string>
<string>{{408,0},{100,112}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>GetUp1_5.png</key>
<dict>
@@ -555,7 +555,7 @@
<key>spriteSourceSize</key>
<string>{106,93}</string>
<key>textureRect</key>
<string>{{507,328},{106,93}}</string>
<string>{{570,219},{106,93}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -570,7 +570,7 @@
<key>spriteSourceSize</key>
<string>{106,79}</string>
<key>textureRect</key>
<string>{{542,217},{106,79}}</string>
<string>{{571,108},{106,79}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -585,7 +585,7 @@
<key>spriteSourceSize</key>
<string>{73,87}</string>
<key>textureRect</key>
<string>{{1307,280},{73,87}}</string>
<string>{{1382,376},{73,87}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -600,9 +600,9 @@
<key>spriteSourceSize</key>
<string>{67,90}</string>
<key>textureRect</key>
<string>{{1413,74},{67,90}}</string>
<string>{{1403,90},{67,90}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>GetUp1_9.png</key>
<dict>
@@ -615,7 +615,7 @@
<key>spriteSourceSize</key>
<string>{58,97}</string>
<key>textureRect</key>
<string>{{1023,194},{58,97}}</string>
<string>{{983,388},{58,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -630,7 +630,7 @@
<key>spriteSourceSize</key>
<string>{58,95}</string>
<key>textureRect</key>
<string>{{1090,386},{58,95}}</string>
<string>{{1219,0},{58,95}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -645,7 +645,7 @@
<key>spriteSourceSize</key>
<string>{58,97}</string>
<key>textureRect</key>
<string>{{1029,97},{58,97}}</string>
<string>{{1024,291},{58,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -660,7 +660,7 @@
<key>spriteSourceSize</key>
<string>{60,94}</string>
<key>textureRect</key>
<string>{{1148,386},{60,94}}</string>
<string>{{1179,385},{60,94}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -675,7 +675,7 @@
<key>spriteSourceSize</key>
<string>{58,97}</string>
<key>textureRect</key>
<string>{{1081,194},{58,97}}</string>
<string>{{1036,194},{58,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -690,7 +690,7 @@
<key>spriteSourceSize</key>
<string>{58,97}</string>
<key>textureRect</key>
<string>{{1068,0},{58,97}}</string>
<string>{{1041,388},{58,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -705,9 +705,9 @@
<key>spriteSourceSize</key>
<string>{60,95}</string>
<key>textureRect</key>
<string>{{1206,0},{60,95}}</string>
<string>{{546,440},{60,95}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Idle1_5.png</key>
<dict>
@@ -720,7 +720,7 @@
<key>spriteSourceSize</key>
<string>{60,94}</string>
<key>textureRect</key>
<string>{{1164,288},{60,94}}</string>
<string>{{1239,385},{60,94}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -735,7 +735,7 @@
<key>spriteSourceSize</key>
<string>{59,93}</string>
<key>textureRect</key>
<string>{{789,403},{59,93}}</string>
<string>{{1248,191},{59,93}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -750,7 +750,7 @@
<key>spriteSourceSize</key>
<string>{58,93}</string>
<key>textureRect</key>
<string>{{1266,0},{58,93}}</string>
<string>{{1277,0},{58,93}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -765,7 +765,7 @@
<key>spriteSourceSize</key>
<string>{59,93}</string>
<key>textureRect</key>
<string>{{1244,95},{59,93}}</string>
<string>{{1254,95},{59,93}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -780,7 +780,7 @@
<key>spriteSourceSize</key>
<string>{60,94}</string>
<key>textureRect</key>
<string>{{1217,190},{60,94}}</string>
<string>{{1246,288},{60,94}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -795,7 +795,7 @@
<key>spriteSourceSize</key>
<string>{77,68}</string>
<key>textureRect</key>
<string>{{1437,417},{77,68}}</string>
<string>{{1473,291},{77,68}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -810,7 +810,7 @@
<key>spriteSourceSize</key>
<string>{118,76}</string>
<key>textureRect</key>
<string>{{215,278},{118,76}}</string>
<string>{{196,284},{118,76}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -825,7 +825,7 @@
<key>spriteSourceSize</key>
<string>{104,65}</string>
<key>textureRect</key>
<string>{{617,0},{104,65}}</string>
<string>{{650,106},{104,65}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -840,9 +840,9 @@
<key>spriteSourceSize</key>
<string>{80,66}</string>
<key>textureRect</key>
<string>{{1380,285},{80,66}}</string>
<string>{{1473,368},{80,66}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirAtk1_12.png</key>
<dict>
@@ -855,7 +855,7 @@
<key>spriteSourceSize</key>
<string>{102,67}</string>
<key>textureRect</key>
<string>{{664,104},{102,67}}</string>
<string>{{715,104},{102,67}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -870,9 +870,9 @@
<key>spriteSourceSize</key>
<string>{79,66}</string>
<key>textureRect</key>
<string>{{1339,201},{79,66}}</string>
<string>{{1470,90},{79,66}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirAtk1_3.png</key>
<dict>
@@ -885,7 +885,7 @@
<key>spriteSourceSize</key>
<string>{124,64}</string>
<key>textureRect</key>
<string>{{78,0},{124,64}}</string>
<string>{{156,0},{124,64}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -900,7 +900,7 @@
<key>spriteSourceSize</key>
<string>{104,64}</string>
<key>textureRect</key>
<string>{{600,323},{104,64}}</string>
<string>{{691,0},{104,64}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -915,7 +915,7 @@
<key>spriteSourceSize</key>
<string>{79,61}</string>
<key>textureRect</key>
<string>{{1376,417},{79,61}}</string>
<string>{{1484,0},{79,61}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -930,7 +930,7 @@
<key>spriteSourceSize</key>
<string>{124,64}</string>
<key>textureRect</key>
<string>{{142,0},{124,64}}</string>
<string>{{160,124},{124,64}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -945,7 +945,7 @@
<key>spriteSourceSize</key>
<string>{106,67}</string>
<key>textureRect</key>
<string>{{597,107},{106,67}}</string>
<string>{{624,0},{106,67}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -960,7 +960,7 @@
<key>spriteSourceSize</key>
<string>{79,66}</string>
<key>textureRect</key>
<string>{{1380,351},{79,66}}</string>
<string>{{1470,156},{79,66}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -975,7 +975,7 @@
<key>spriteSourceSize</key>
<string>{118,64}</string>
<key>textureRect</key>
<string>{{291,243},{118,64}}</string>
<string>{{272,284},{118,64}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -990,9 +990,9 @@
<key>spriteSourceSize</key>
<string>{71,119}</string>
<key>textureRect</key>
<string>{{242,0},{71,119}}</string>
<string>{{100,429},{71,119}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_1.png</key>
<dict>
@@ -1005,7 +1005,7 @@
<key>spriteSourceSize</key>
<string>{71,119}</string>
<key>textureRect</key>
<string>{{313,0},{71,119}}</string>
<string>{{282,0},{71,119}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1020,7 +1020,7 @@
<key>spriteSourceSize</key>
<string>{55,114}</string>
<key>textureRect</key>
<string>{{353,361},{55,114}}</string>
<string>{{353,0},{55,114}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1035,7 +1035,7 @@
<key>spriteSourceSize</key>
<string>{62,124}</string>
<key>textureRect</key>
<string>{{160,124},{62,124}}</string>
<string>{{220,0},{62,124}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1050,9 +1050,9 @@
<key>spriteSourceSize</key>
<string>{74,90}</string>
<key>textureRect</key>
<string>{{1413,0},{74,90}}</string>
<string>{{1369,184},{74,90}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirIdle1_3.png</key>
<dict>
@@ -1065,7 +1065,7 @@
<key>spriteSourceSize</key>
<string>{110,54}</string>
<key>textureRect</key>
<string>{{440,0},{110,54}}</string>
<string>{{508,0},{110,54}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1080,7 +1080,7 @@
<key>spriteSourceSize</key>
<string>{85,88}</string>
<key>textureRect</key>
<string>{{1291,376},{85,88}}</string>
<string>{{736,412},{85,88}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1095,7 +1095,7 @@
<key>spriteSourceSize</key>
<string>{64,112}</string>
<key>textureRect</key>
<string>{{421,235},{64,112}}</string>
<string>{{445,227},{64,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1110,7 +1110,7 @@
<key>spriteSourceSize</key>
<string>{62,107}</string>
<key>textureRect</key>
<string>{{555,0},{62,107}}</string>
<string>{{546,333},{62,107}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1125,9 +1125,9 @@
<key>spriteSourceSize</key>
<string>{85,84}</string>
<key>textureRect</key>
<string>{{1405,201},{85,84}}</string>
<string>{{1389,291},{85,84}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_8.png</key>
<dict>
@@ -1140,7 +1140,7 @@
<key>spriteSourceSize</key>
<string>{109,61}</string>
<key>textureRect</key>
<string>{{494,0},{109,61}}</string>
<string>{{509,224},{109,61}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1155,7 +1155,7 @@
<key>spriteSourceSize</key>
<string>{78,95}</string>
<key>textureRect</key>
<string>{{1139,193},{78,95}}</string>
<string>{{1176,96},{78,95}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1170,7 +1170,7 @@
<key>spriteSourceSize</key>
<string>{115,56}</string>
<key>textureRect</key>
<string>{{384,0},{115,56}}</string>
<string>{{347,119},{115,56}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1185,7 +1185,7 @@
<key>spriteSourceSize</key>
<string>{109,57}</string>
<key>textureRect</key>
<string>{{485,219},{109,57}}</string>
<string>{{514,110},{109,57}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1200,7 +1200,7 @@
<key>spriteSourceSize</key>
<string>{108,62}</string>
<key>textureRect</key>
<string>{{535,109},{108,62}}</string>
<string>{{562,0},{108,62}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1215,9 +1215,9 @@
<key>spriteSourceSize</key>
<string>{123,36}</string>
<key>textureRect</key>
<string>{{206,0},{123,36}}</string>
<string>{{160,248},{123,36}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>LayDown1_4.png</key>
<dict>
@@ -1230,7 +1230,52 @@
<key>spriteSourceSize</key>
<string>{123,30}</string>
<key>textureRect</key>
<string>{{160,248},{123,30}}</string>
<string>{{224,124},{123,30}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>TurnAround1_1.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{74,96}</string>
<key>spriteSourceSize</key>
<string>{74,96}</string>
<key>textureRect</key>
<string>{{1094,194},{74,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>TurnAround1_2.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{74,96}</string>
<key>spriteSourceSize</key>
<string>{74,96}</string>
<key>textureRect</key>
<string>{{1102,97},{74,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>TurnAround1_3.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{74,96}</string>
<key>spriteSourceSize</key>
<string>{74,96}</string>
<key>textureRect</key>
<string>{{1145,0},{74,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1245,9 +1290,9 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{692,415},{81,97}}</string>
<string>{{219,402},{81,97}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Walking_10.png</key>
<dict>
@@ -1260,7 +1305,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{760,306},{81,97}}</string>
<string>{{300,402},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1275,7 +1320,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{780,201},{81,97}}</string>
<string>{{821,0},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1290,7 +1335,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{786,99},{81,97}}</string>
<string>{{793,200},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1305,7 +1350,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{825,0},{81,97}}</string>
<string>{{859,97},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1320,7 +1365,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{841,298},{81,97}}</string>
<string>{{902,0},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1335,7 +1380,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{848,395},{81,97}}</string>
<string>{{800,297},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1350,7 +1395,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{861,196},{81,97}}</string>
<string>{{874,194},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1365,7 +1410,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{867,97},{81,97}}</string>
<string>{{940,97},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1380,7 +1425,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{906,0},{81,97}}</string>
<string>{{983,0},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1395,7 +1440,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{922,293},{81,97}}</string>
<string>{{821,394},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1410,7 +1455,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{942,194},{81,97}}</string>
<string>{{881,291},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1425,7 +1470,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{948,97},{81,97}}</string>
<string>{{955,194},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1440,7 +1485,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{987,0},{81,97}}</string>
<string>{{1021,97},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1455,7 +1500,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{929,390},{81,97}}</string>
<string>{{1064,0},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1470,7 +1515,7 @@
<key>spriteSourceSize</key>
<string>{81,97}</string>
<key>textureRect</key>
<string>{{1003,291},{81,97}}</string>
<string>{{902,388},{81,97}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1486,9 +1531,9 @@
<key>realTextureFileName</key>
<string>MonkGirl.png</string>
<key>size</key>
<string>{1505,496}</string>
<string>{1549,500}</string>
<key>smartupdate</key>
<string>$TexturePacker:SmartUpdate:8383576ddc6ed0fb9e6adcbc98ec9c07:b0caf27c9f592741053365a3d87b3473:7b088363a1f16e4f4ff313aecc52227b$</string>
<string>$TexturePacker:SmartUpdate:f2fd96a7a4bba5a2e1c4622dcb63e1f2:17c698372c46bf0be82704dd808cd6f4:7b088363a1f16e4f4ff313aecc52227b$</string>
<key>textureFileName</key>
<string>MonkGirl.png</string>
</dict>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View File

@@ -9,10 +9,10 @@
</data>
</layer>
<objectgroup id="1" name="PlayerStartingPos">
<object id="135" x="840" y="530">
<object id="135" x="1400" y="580">
<point/>
</object>
<object id="137" x="959" y="532">
<object id="137" x="1500" y="580">
<point/>
</object>
</objectgroup>

View File

@@ -9,9 +9,9 @@ message PlayerDownsync {
int32 virtualGridX = 2;
int32 virtualGridY = 3;
int32 dirX = 4;
int32 dirY = 5; // "dirX" and "dirY" determines character facing
int32 dirY = 5;
int32 velX = 6;
int32 velY = 7; // "velX" and "velY" is used to record the accumulated effect by accelerations (including gravity)
int32 velY = 7; // "velX" and "velY" is used to record the accumulated effect by inertia and accelerations (including gravity)
int32 speed = 8; // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
int32 battleState = 9;
int32 joinIndex = 10;
@@ -36,6 +36,8 @@ message PlayerDownsync {
int32 onWallNormX = 27;
int32 onWallNormY = 28;
bool capturedByInertia = 29; // like "inAir", its by design a standalone field only inferred by the calc result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState"
string name = 997;
string displayName = 998;
string avatar = 999;
@@ -51,6 +53,7 @@ message InputFrameDecoded {
message InputFrameUpsync {
int32 inputFrameId = 1;
uint64 encoded = 2;
int32 joinIndex = 3;
}
message InputFrameDownsync {
@@ -81,6 +84,7 @@ message WsResp {
RoomDownsyncFrame rdf = 4;
repeated InputFrameDownsync inputFrameDownsyncBatch = 5;
BattleColliderInfo bciFrame = 6;
int32 peerJoinIndex = 7; // Only used when "InputsBufferSnapshot.peerJoinIndex" is used.
}
message InputsBufferSnapshot {
@@ -88,6 +92,7 @@ message InputsBufferSnapshot {
uint64 unconfirmedMask = 2;
repeated InputFrameDownsync toSendInputFrameDownsyncs = 3;
bool shouldForceResync = 4;
int32 peerJoinIndex = 5; // Only used when "WsResp.peerJoinIndex" is used.
}
message MeleeBullet {

View File

@@ -8,7 +8,8 @@
"__id__": 1
},
"optimizationPolicy": 0,
"asyncLoadAssets": false
"asyncLoadAssets": false,
"readonly": false
},
{
"__type__": "cc.Node",
@@ -27,20 +28,19 @@
},
{
"__id__": 11
},
{
"__id__": 14
}
],
"_active": true,
"_level": 1,
"_components": [
{
"__id__": 14
},
{
"__id__": 15
"__id__": 17
}
],
"_prefab": {
"__id__": 16
"__id__": 18
},
"_opacity": 255,
"_color": {
@@ -52,25 +52,14 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1024,
"height": 1920
"width": 960,
"height": 640
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
@@ -86,18 +75,29 @@
1,
1
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "WhiteStars",
"_name": "Background",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_level": 2,
"_components": [
{
"__id__": 3
@@ -109,37 +109,26 @@
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"r": 0,
"g": 163,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 268,
"height": 112
"width": 1920,
"height": 1280
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
-16,
0,
0,
0,
0,
@@ -150,7 +139,19 @@
1,
1
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Sprite",
@@ -160,11 +161,18 @@
"__id__": 2
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "1a2d934e-9d6d-45bf-83c6-564586cc8400"
"__uuid__": "637f31c2-c53e-4dec-ae11-d56c0c6177ad"
},
"_type": 0,
"_sizeMode": 1,
"_sizeMode": 0,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
@@ -174,12 +182,9 @@
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_state": 0,
"_atlas": {
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
},
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_id": ""
},
{
@@ -190,7 +195,7 @@
"asset": {
"__uuid__": "230eeb1f-e0f9-4a41-ab6c-05b3771cbf3e"
},
"fileId": "50Mjaee6xFXLrZ/mSBD3P5",
"fileId": "83iQr+5XNNF5E2qjV+WUp0",
"sync": false
},
{
@@ -202,7 +207,6 @@
},
"_children": [],
"_active": true,
"_level": 3,
"_components": [
{
"__id__": 6
@@ -229,17 +233,6 @@
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
@@ -255,7 +248,19 @@
1,
1
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Sprite",
@@ -265,6 +270,13 @@
"__id__": 5
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "75a2c1e3-2c22-480c-9572-eb65f4a554e1"
},
@@ -279,12 +291,9 @@
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_state": 0,
"_atlas": {
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
},
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_id": ""
},
{
@@ -307,7 +316,6 @@
},
"_children": [],
"_active": true,
"_level": 2,
"_components": [
{
"__id__": 9
@@ -327,24 +335,13 @@
"_contentSize": {
"__type__": "cc.Size",
"width": 111.23,
"height": 200
"height": 252
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
@@ -360,7 +357,19 @@
0.66667,
0.66667
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Label",
@@ -370,6 +379,11 @@
"__id__": 8
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_useOriginalSize": false,
"_string": "3",
"_N$string": "3",
@@ -407,7 +421,6 @@
},
"_children": [],
"_active": true,
"_level": 2,
"_components": [
{
"__id__": 12
@@ -434,17 +447,6 @@
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
@@ -460,7 +462,19 @@
1,
1
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Sprite",
@@ -470,6 +484,13 @@
"__id__": 11
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "637f31c2-c53e-4dec-ae11-d56c0c6177ad"
},
@@ -484,12 +505,9 @@
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_state": 0,
"_atlas": {
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
},
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_id": ""
},
{
@@ -503,6 +521,115 @@
"fileId": "21dxpL7zlKIIDhUt+GIMbg",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "WhiteStars",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 15
}
],
"_prefab": {
"__id__": 16
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 268,
"height": 112
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
-16,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 14
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "1a2d934e-9d6d-45bf-83c6-564586cc8400"
},
"_type": 0,
"_sizeMode": 1,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": {
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "230eeb1f-e0f9-4a41-ab6c-05b3771cbf3e"
},
"fileId": "50Mjaee6xFXLrZ/mSBD3P5",
"sync": false
},
{
"__type__": "6a3d6Y6Ki1BiqAVSKIRdwRl",
"_name": "",
@@ -516,34 +643,6 @@
},
"_id": ""
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"_spriteFrame": {
"__uuid__": "334d4f93-b007-49e8-9268-35891d4f4ebb"
},
"_type": 0,
"_sizeMode": 1,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_state": 0,
"_atlas": null,
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"ver": "1.2.5",
"uuid": "3ed4c7bc-79d0-4075-a563-d5a58ae798f9",
"uuid": "dc804c5c-ff76-445e-ac69-52269055c3c5",
"optimizationPolicy": "AUTO",
"asyncLoadAssets": false,
"readonly": false,

View File

@@ -21,20 +21,20 @@
"__id__": 2
},
{
"__id__": 10
"__id__": 5
}
],
"_active": true,
"_components": [
{
"__id__": 13
"__id__": 12
},
{
"__id__": 14
"__id__": 13
}
],
"_prefab": {
"__id__": 15
"__id__": 14
},
"_opacity": 255,
"_color": {
@@ -46,8 +46,72 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1024,
"height": 1920
"width": 960,
"height": 640
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
480,
320,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "Background",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
}
],
"_prefab": {
"__id__": 4
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1920,
"height": 1280
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -83,6 +147,51 @@
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "637f31c2-c53e-4dec-ae11-d56c0c6177ad"
},
"_type": 0,
"_sizeMode": 0,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": {
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "32b8e752-8362-4783-a4a6-1160af8b7109"
},
"fileId": "a7oR1cZvVO/pp9QJgLnJyt",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "modeButton",
@@ -92,20 +201,20 @@
},
"_children": [
{
"__id__": 3
"__id__": 6
}
],
"_active": true,
"_components": [
{
"__id__": 7
"__id__": 9
},
{
"__id__": 8
"__id__": 10
}
],
"_prefab": {
"__id__": 9
"__id__": 11
},
"_opacity": 255,
"_color": {
@@ -117,8 +226,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 280,
"height": 130
"width": 240,
"height": 100
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -130,7 +239,7 @@
"ctor": "Float64Array",
"array": [
0,
-564,
-90.495,
0,
0,
0,
@@ -159,20 +268,17 @@
"_name": "Label",
"_objFlags": 0,
"_parent": {
"__id__": 2
"__id__": 5
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 4
},
{
"__id__": 5
"__id__": 7
}
],
"_prefab": {
"__id__": 6
"__id__": 8
},
"_opacity": 255,
"_color": {
@@ -226,7 +332,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 3
"__id__": 6
},
"_enabled": true,
"_materials": [
@@ -235,8 +341,8 @@
}
],
"_useOriginalSize": false,
"_string": "gameRule.mode",
"_N$string": "gameRule.mode",
"_string": "1 v 1",
"_N$string": "1 v 1",
"_fontSize": 55,
"_lineHeight": 50,
"_enableWrapText": false,
@@ -251,17 +357,6 @@
"_N$cacheMode": 0,
"_id": ""
},
{
"__type__": "744dcs4DCdNprNhG0xwq6FK",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 3
},
"_enabled": true,
"_dataID": "gameRule.mode",
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
@@ -278,7 +373,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
"__id__": 5
},
"_enabled": true,
"_materials": [
@@ -312,7 +407,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
"__id__": 5
},
"_enabled": true,
"_normalMaterial": null,
@@ -375,7 +470,7 @@
"hoverSprite": null,
"_N$disabledSprite": null,
"_N$target": {
"__id__": 2
"__id__": 5
},
"_id": ""
},
@@ -390,115 +485,6 @@
"fileId": "c54lqSflFD8ogSYAhsAkKh",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "decoration",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 11
}
],
"_prefab": {
"__id__": 12
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 543,
"height": 117
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
-312,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 10
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "153d890a-fc37-4d59-8779-93a8fb19fa85"
},
"_type": 0,
"_sizeMode": 1,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": {
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "32b8e752-8362-4783-a4a6-1160af8b7109"
},
"fileId": "1bbMLAzntHZpEudL8lM/Lx",
"sync": false
},
{
"__type__": "dd92bKVy8FJY7uq3ieoNZCZ",
"_name": "",
@@ -508,41 +494,36 @@
},
"_enabled": true,
"modeButton": {
"__id__": 8
"__id__": 10
},
"mapNode": null,
"_id": ""
},
{
"__type__": "cc.Sprite",
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "7838f276-ab48-445a-b858-937dd27d9520"
},
"_type": 0,
"_sizeMode": 0,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"alignMode": 1,
"_target": null,
"_alignFlags": 18,
"_left": 0,
"_right": 0,
"_top": 0,
"_bottom": 0,
"_verticalCenter": 0,
"_horizontalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 0,
"_originalHeight": 0,
"_id": ""
},
{

View File

@@ -8,7 +8,8 @@
"__id__": 1
},
"optimizationPolicy": 0,
"asyncLoadAssets": false
"asyncLoadAssets": false,
"readonly": false
},
{
"__type__": "cc.Node",
@@ -20,18 +21,17 @@
"__id__": 2
},
{
"__id__": 6
"__id__": 5
}
],
"_active": true,
"_level": 1,
"_components": [
{
"__id__": 9
"__id__": 8
}
],
"_prefab": {
"__id__": 10
"__id__": 9
},
"_opacity": 255,
"_color": {
@@ -51,24 +51,12 @@
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"_zIndex": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
512,
0,
480,
480,
0,
0,
0,
@@ -78,7 +66,19 @@
1,
1
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Node",
@@ -89,17 +89,13 @@
},
"_children": [],
"_active": true,
"_level": 0,
"_components": [
{
"__id__": 3
},
{
"__id__": 4
}
],
"_prefab": {
"__id__": 5
"__id__": 4
},
"_opacity": 255,
"_color": {
@@ -111,32 +107,20 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 303.5,
"height": 30
"width": 805.7,
"height": 35.28
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"_zIndex": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
210,
-150,
0,
0,
0,
@@ -146,7 +130,19 @@
1,
1
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Label",
@@ -156,32 +152,26 @@
"__id__": 2
},
"_enabled": true,
"_srcBlendFactor": 1,
"_dstBlendFactor": 771,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_useOriginalSize": false,
"_string": "login.tips.loginSuccess",
"_N$string": "login.tips.loginSuccess",
"_fontSize": 30,
"_lineHeight": 30,
"_string": "Logged in successfully, loading game resources...",
"_N$string": "Logged in successfully, loading game resources...",
"_fontSize": 28,
"_lineHeight": 28,
"_enableWrapText": true,
"_N$file": null,
"_isSystemFontUsed": true,
"_spacingX": 0,
"_batchAsBitmap": false,
"_N$horizontalAlign": 1,
"_N$verticalAlign": 1,
"_N$fontFamily": "Arial",
"_N$overflow": 0,
"_id": ""
},
{
"__type__": "744dcs4DCdNprNhG0xwq6FK",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
},
"_enabled": true,
"_dataID": "login.tips.loginSuccess",
"_N$overflow": 3,
"_N$cacheMode": 0,
"_id": ""
},
{
@@ -204,14 +194,13 @@
},
"_children": [],
"_active": true,
"_level": 0,
"_components": [
{
"__id__": 7
"__id__": 6
}
],
"_prefab": {
"__id__": 8
"__id__": 7
},
"_opacity": 255,
"_color": {
@@ -231,24 +220,12 @@
"x": 0.5,
"y": 0.5
},
"_quat": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_skewX": 0,
"_skewY": 0,
"_zIndex": 0,
"groupIndex": 0,
"_id": "",
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
333,
0,
0,
0,
0,
@@ -258,16 +235,29 @@
1,
1
]
}
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 6
"__id__": 5
},
"_enabled": true,
"_materials": [],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": null,
@@ -282,7 +272,6 @@
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_state": 0,
"_atlas": null,
"_id": ""
},
@@ -307,7 +296,7 @@
"_enabled": true,
"alignMode": 0,
"_target": null,
"_alignFlags": 20,
"_alignFlags": 18,
"_left": 0,
"_right": 0,
"_top": 0,

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

View File

@@ -1,34 +0,0 @@
{
"ver": "2.3.3",
"uuid": "825df908-a4cb-449d-9731-8ef53f3fd44f",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"platformSettings": {},
"subMetas": {
"MiniGame_Background": {
"ver": "1.0.4",
"uuid": "7838f276-ab48-445a-b858-937dd27d9520",
"rawTextureUuid": "825df908-a4cb-449d-9731-8ef53f3fd44f",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 750,
"height": 1624,
"rawWidth": 750,
"rawHeight": 1624,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

View File

@@ -1,34 +0,0 @@
{
"ver": "2.3.3",
"uuid": "94b8bb09-e8ac-4402-a933-b79f01b5a813",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"platformSettings": {},
"subMetas": {
"MiniGame_Blackboard": {
"ver": "1.0.4",
"uuid": "334d4f93-b007-49e8-9268-35891d4f4ebb",
"rawTextureUuid": "94b8bb09-e8ac-4402-a933-b79f01b5a813",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 1024,
"height": 1920,
"rawWidth": 1024,
"rawHeight": 1920,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}

View File

@@ -72,25 +72,25 @@
"__id__": 3
},
{
"__id__": 8
"__id__": 9
}
],
"_active": true,
"_components": [
{
"__id__": 37
},
{
"__id__": 38
},
{
"__id__": 39
},
{
"__id__": 40
},
{
"__id__": 41
},
{
"__id__": 42
},
{
"__id__": 43
},
{
"__id__": 44
}
],
"_prefab": null,
@@ -104,8 +104,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1024,
"height": 1920
"width": 960,
"height": 640
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -116,8 +116,8 @@
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
512,
960,
480,
320,
0,
0,
0,
@@ -158,7 +158,7 @@
"__id__": 5
},
{
"__id__": 36
"__id__": 39
}
],
"_prefab": null,
@@ -172,8 +172,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 2048,
"height": 2048
"width": 960,
"height": 640
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -247,10 +247,10 @@
"__uuid__": "670b477e-61a1-4778-879b-35913f7c79d2"
},
"boundRoomIdLabel": {
"__id__": 15
"__id__": 16
},
"countdownLabel": {
"__id__": 21
"__id__": 23
},
"resultPanelPrefab": {
"__uuid__": "c4cfe3bd-c59e-4d5b-95cb-c933b120e184"
@@ -259,7 +259,7 @@
"__uuid__": "32b8e752-8362-4783-a4a6-1160af8b7109"
},
"findingPlayerPrefab": {
"__uuid__": "3ed4c7bc-79d0-4075-a563-d5a58ae798f9"
"__uuid__": "dc804c5c-ff76-445e-ac69-52269055c3c5"
},
"countdownToBeginGamePrefab": {
"__uuid__": "230eeb1f-e0f9-4a41-ab6c-05b3771cbf3e"
@@ -283,13 +283,13 @@
},
"_children": [
{
"__id__": 30
"__id__": 33
}
],
"_active": true,
"_components": [
{
"__id__": 35
"__id__": 38
}
],
"_prefab": null,
@@ -315,16 +315,16 @@
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
-500,
-199.439,
-172.557,
0,
0,
0,
0,
1,
0.66667,
0.66667,
0.66667
0.4,
0.4,
0.4
]
},
"_eulerAngles": {
@@ -342,30 +342,31 @@
},
{
"__type__": "cc.Node",
"_name": "WidgetsAboveAll",
"_name": "Interactive",
"_objFlags": 0,
"_parent": {
"__id__": 8
},
"_children": [
{
"__id__": 10
},
{
"__id__": 6
},
{
"__id__": 20
},
{
"__id__": 22
},
{
"__id__": 26
"__id__": 24
},
{
"__id__": 28
}
],
"_active": true,
"_components": [],
"_components": [
{
"__id__": 32
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
@@ -412,6 +413,75 @@
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "bb5Zj3NPxJgrEYDllBW7Gj"
},
{
"__type__": "cc.Node",
"_name": "WidgetsAboveAll",
"_objFlags": 0,
"_parent": {
"__id__": 9
},
"_children": [
{
"__id__": 11
},
{
"__id__": 7
}
],
"_active": true,
"_components": [
{
"__id__": 21
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1280,
"height": 1280
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "c6fPdAUURDX69j0zTeIFZv"
},
{
@@ -423,13 +493,13 @@
},
"_children": [
{
"__id__": 7
"__id__": 8
}
],
"_active": true,
"_components": [
{
"__id__": 9
"__id__": 10
}
],
"_prefab": null,
@@ -485,7 +555,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 8
"__id__": 9
},
"_enabled": true,
"_cullingMask": 4294967295,
@@ -521,20 +591,20 @@
"_name": "DebugInfo",
"_objFlags": 0,
"_parent": {
"__id__": 7
"__id__": 8
},
"_children": [
{
"__id__": 11
"__id__": 12
}
],
"_active": true,
"_components": [
{
"__id__": 18
"__id__": 19
},
{
"__id__": 19
"__id__": 20
}
],
"_prefab": null,
@@ -560,8 +630,8 @@
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
-478,
627,
-447.294,
135.702,
0,
0,
0,
@@ -590,23 +660,23 @@
"_name": "RoomIdIndicator",
"_objFlags": 0,
"_parent": {
"__id__": 10
"__id__": 11
},
"_children": [
{
"__id__": 12
"__id__": 13
},
{
"__id__": 14
"__id__": 15
}
],
"_active": false,
"_components": [
{
"__id__": 16
"__id__": 17
},
{
"__id__": 17
"__id__": 18
}
],
"_prefab": null,
@@ -662,13 +732,13 @@
"_name": "label",
"_objFlags": 0,
"_parent": {
"__id__": 11
"__id__": 12
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 13
"__id__": 14
}
],
"_prefab": null,
@@ -724,7 +794,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 12
"__id__": 13
},
"_enabled": true,
"_materials": [],
@@ -752,13 +822,13 @@
"_name": "BoundRoomIdLabel",
"_objFlags": 0,
"_parent": {
"__id__": 11
"__id__": 12
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 15
"__id__": 16
}
],
"_prefab": null,
@@ -814,7 +884,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 14
"__id__": 15
},
"_enabled": true,
"_materials": [],
@@ -842,7 +912,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 11
"__id__": 12
},
"_enabled": true,
"_layoutSize": {
@@ -875,7 +945,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 11
"__id__": 12
},
"_enabled": true,
"_materials": [],
@@ -905,7 +975,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 10
"__id__": 11
},
"_enabled": true,
"_materials": [],
@@ -931,7 +1001,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 10
"__id__": 11
},
"_enabled": true,
"_layoutSize": {
@@ -959,6 +1029,33 @@
"_N$affectedByScale": false,
"_id": "f6GkgYwn9JvKLqbGG1zmeD"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 8
},
"_enabled": true,
"alignMode": 2,
"_target": null,
"_alignFlags": 18,
"_left": 0,
"_right": 0,
"_top": 0,
"_bottom": 0,
"_verticalCenter": 0,
"_horizontalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 0,
"_originalHeight": 0,
"_id": "aenJ9ZDDRKDoS7u5MxeZOb"
},
{
"__type__": "cc.Node",
"_name": "CountdownSeconds",
@@ -970,7 +1067,7 @@
"_active": true,
"_components": [
{
"__id__": 21
"__id__": 23
}
],
"_prefab": null,
@@ -997,7 +1094,7 @@
"ctor": "Float64Array",
"array": [
0,
591,
181.094,
0,
0,
0,
@@ -1026,7 +1123,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 20
"__id__": 22
},
"_enabled": true,
"_materials": [
@@ -1060,7 +1157,7 @@
},
"_children": [
{
"__id__": 23
"__id__": 25
}
],
"_active": true,
@@ -1088,16 +1185,16 @@
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
143.689,
-584.849,
178,
-179.607,
0,
0,
0,
0,
1,
0.66667,
0.66667,
0.66667
0.5,
0.5,
0.5
]
},
"_eulerAngles": {
@@ -1118,16 +1215,16 @@
"_name": "Background",
"_objFlags": 0,
"_parent": {
"__id__": 22
"__id__": 24
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 24
"__id__": 26
},
{
"__id__": 25
"__id__": 27
}
],
"_prefab": null,
@@ -1183,7 +1280,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 23
"__id__": 25
},
"_enabled": true,
"_materials": [
@@ -1217,7 +1314,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 23
"__id__": 25
},
"_enabled": true,
"alignMode": 0,
@@ -1248,7 +1345,7 @@
},
"_children": [
{
"__id__": 27
"__id__": 29
}
],
"_active": true,
@@ -1276,16 +1373,16 @@
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
370.368,
-424.647,
395,
-123.879,
0,
0,
0,
0,
1,
0.66667,
0.66667,
0.66667
0.5,
0.5,
0.5
]
},
"_eulerAngles": {
@@ -1306,16 +1403,16 @@
"_name": "Background",
"_objFlags": 0,
"_parent": {
"__id__": 26
"__id__": 28
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 28
"__id__": 30
},
{
"__id__": 29
"__id__": 31
}
],
"_prefab": null,
@@ -1371,7 +1468,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 27
"__id__": 29
},
"_enabled": true,
"_materials": [
@@ -1405,7 +1502,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 27
"__id__": 29
},
"_enabled": true,
"alignMode": 0,
@@ -1427,6 +1524,33 @@
"_originalHeight": 40,
"_id": "5bXB50moJH9aH7RcbRuSS5"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 7
},
"_enabled": true,
"alignMode": 1,
"_target": null,
"_alignFlags": 20,
"_left": 0,
"_right": 0,
"_top": 0,
"_bottom": 640,
"_verticalCenter": 0,
"_horizontalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 0,
"_originalHeight": 0,
"_id": "60S5//1JxMULAtkfxKep87"
},
{
"__type__": "cc.Node",
"_name": "JoystickBG",
@@ -1436,16 +1560,16 @@
},
"_children": [
{
"__id__": 31
"__id__": 34
}
],
"_active": true,
"_components": [
{
"__id__": 33
"__id__": 36
},
{
"__id__": 34
"__id__": 37
}
],
"_prefab": null,
@@ -1501,13 +1625,13 @@
"_name": "Joystick",
"_objFlags": 0,
"_parent": {
"__id__": 30
"__id__": 33
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 32
"__id__": 35
}
],
"_prefab": null,
@@ -1563,7 +1687,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 31
"__id__": 34
},
"_enabled": true,
"_materials": [
@@ -1597,7 +1721,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 30
"__id__": 33
},
"_enabled": true,
"_materials": [
@@ -1631,7 +1755,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 30
"__id__": 33
},
"_enabled": true,
"alignMode": 0,
@@ -1688,21 +1812,11 @@
"__id__": 3
},
"_enabled": true,
"BGMEffect": {
"__uuid__": "64a79efa-97de-4cb5-b2a9-01500c60573a"
},
"crashedByTrapBullet": {
"__uuid__": "1d604e42-8cee-466f-884d-e74cae21ce3b"
},
"highScoreTreasurePicked": {
"__uuid__": "0164d22c-d965-461f-867e-b30e2d56cc5c"
},
"treasurePicked": {
"__uuid__": "7704b97e-6367-420c-b7af-d0750a2bbb30"
},
"countDown10SecToEnd": {
"__uuid__": "261d1d7d-a5cc-4cb7-a737-194427055fd4"
},
"BGMEffect": null,
"crashedByTrapBullet": null,
"highScoreTreasurePicked": null,
"treasurePicked": null,
"countDown10SecToEnd": null,
"mapNode": {
"__id__": 3
},
@@ -1718,8 +1832,8 @@
"_enabled": true,
"_designResolution": {
"__type__": "cc.Size",
"width": 1024,
"height": 1920
"width": 960,
"height": 640
},
"_fitWidth": true,
"_fitHeight": false,
@@ -1760,9 +1874,9 @@
"__id__": 2
},
"_enabled": true,
"alignMode": 0,
"alignMode": 1,
"_target": null,
"_alignFlags": 0,
"_alignFlags": 18,
"_left": 6240,
"_right": -4000,
"_top": -8320,
@@ -1794,10 +1908,10 @@
"__id__": 3
},
"stickhead": {
"__id__": 31
"__id__": 34
},
"base": {
"__id__": 30
"__id__": 33
},
"joyStickEps": 0.1,
"magicLeanLowerBound": 0.414,
@@ -1818,10 +1932,10 @@
"linearMovingEps": 0.1,
"scaleByEps": 0.0375,
"btnA": {
"__id__": 22
"__id__": 24
},
"btnB": {
"__id__": 26
"__id__": 28
},
"_id": "e9oVYTr7ROlpp/IrNjBUmR"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,10 +14,6 @@ cc.Class({
type: cc.Node,
default: null
},
myAvatarNode: {
type: cc.Node,
default: null
},
exitBtnNode: {
type: cc.Node,
default: null
@@ -25,8 +21,7 @@ cc.Class({
},
// LIFE-CYCLE CALLBACKS:
onLoad() {
},
onLoad() {},
init() {
if (null != this.firstPlayerInfoNode) {
@@ -70,29 +65,20 @@ cc.Class({
const playerInfoNode = this.playersInfoNode[playerMeta.joinIndex];
if (null == playerInfoNode) {
cc.error("There's no playerInfoNode for joinIndex == ", joinIndex, ", as `this.playerInfoNode` is currently ", this.playersInfoNode);
}
}
playerInfoNode.active = true;
if (2 == playerMeta.joinIndex) {
if (null != this.findingAnimNode) {
if (null != this.findingAnimNode) {
this.findingAnimNode.active = false;
}
}
}
//显示自己的头像名称以及他人的头像名称
for (let i in playerMetas) {
const playerMeta = playerMetas[i];
console.log("Showing playerMeta:", playerMeta);
const playerInfoNode = this.playersInfoNode[playerMeta.joinIndex];
(() => { //远程加载头像
let remoteUrl = playerMeta.avatar;
if (remoteUrl == null || remoteUrl == '') {
cc.log(`No avatar to show for :`);
cc.log(playerMeta);
}
})();
function isEmptyString(str) {
return str == null || str == ''
}

View File

@@ -68,6 +68,8 @@ cc.Class({
// LIFE-CYCLE CALLBACKS:
onLoad() {
cc.view.setOrientation(cc.macro.ORIENTATION_AUTO);
cc.view.enableAutoFullScreen(true);
window.atFirstLocationHref = window.location.href.split('#')[0];
const self = this;

View File

@@ -308,7 +308,7 @@ cc.Class({
const newFireball = newFireballNode.getComponent("Fireball");
newFireballNode.setPosition(cc.v2(Number.MAX_VALUE, Number.MAX_VALUE));
safelyAddChild(self.node, newFireballNode);
setLocalZOrder(newFireballNode, 5);
setLocalZOrder(newFireballNode, 10);
newFireball.lastUsed = -1;
newFireball.bulletLocalId = -1;
const initLookupKey = -(k + 1); // there's definitely no suck "bulletLocalId"
@@ -409,6 +409,9 @@ cc.Class({
},
onLoad() {
cc.view.setOrientation(cc.macro.ORIENTATION_LANDSCAPE);
cc.view.enableAutoFullScreen(true);
const self = this;
window.mapIns = self;
window.forceBigEndianFloatingNumDecoding = self.forceBigEndianFloatingNumDecoding;
@@ -473,7 +476,6 @@ cc.Class({
console.log(`Received parsedBattleColliderInfo via ws`);
// TODO: Upon reconnection, the backend might have already been sending down data that'd trigger "onRoomDownsyncFrame & onInputFrameDownsyncBatch", but frontend could reject those data due to "battleState != PlayerBattleState.ACTIVE".
Object.assign(self, parsedBattleColliderInfo);
self.tooFastDtIntervalMillis = 0.5 * self.rollbackEstimatedDtMillis;
const tiledMapIns = self.node.getComponent(cc.TiledMap);
@@ -607,7 +609,7 @@ cc.Class({
const jsPlayersArr = new Array(pbRdf.playersArr.length).fill(null);
for (let k = 0; k < pbRdf.playersArr.length; ++k) {
const pbPlayer = pbRdf.playersArr[k];
const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.activeSkillId, pbPlayer.activeSkillHit, pbPlayer.framesInvinsible, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.colliderRadius, pbPlayer.inAir, pbPlayer.onWall, pbPlayer.onWallNormX, pbPlayer.onWallNormY, pbPlayer.bulletTeamId, pbPlayer.chCollisionTeamId);
const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.activeSkillId, pbPlayer.activeSkillHit, pbPlayer.framesInvinsible, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.colliderRadius, pbPlayer.inAir, pbPlayer.onWall, pbPlayer.onWallNormX, pbPlayer.onWallNormY, pbPlayer.capturedByInertia, pbPlayer.bulletTeamId, pbPlayer.chCollisionTeamId);
jsPlayersArr[k] = jsPlayer;
}
const jsMeleeBulletsArr = new Array(pbRdf.meleeBullets.length).fill(null);
@@ -837,13 +839,41 @@ cc.Class({
--------------------------------------------------------
*/
// The actual rollback-and-chase would later be executed in update(dt).
console.warn(`Mismatched input detected, resetting chaserRenderFrameId: ${self.chaserRenderFrameId}->${renderFrameId1} by firstPredictedYetIncorrectInputFrameId: ${firstPredictedYetIncorrectInputFrameId}
console.log(`Mismatched input detected, resetting chaserRenderFrameId: ${self.chaserRenderFrameId}->${renderFrameId1} by firstPredictedYetIncorrectInputFrameId: ${firstPredictedYetIncorrectInputFrameId}
lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}
recentInputCache=${self._stringifyRecentInputCache(false)}
batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inputFrameId}]`);
self.chaserRenderFrameId = renderFrameId1;
},
onPeerInputFrameUpsync(peerJoinIndex, batch /* []*pb.InputFrameDownsync */ ) {
// TODO: find some kind of synchronization mechanism against "getOrPrefabInputFrameUpsync"!
// See `<proj-root>/ConcerningEdgeCases.md` for why this method exists.
if (null == batch) {
return;
}
const self = this;
if (!self.recentInputCache) {
return;
}
if (ALL_BATTLE_STATES.IN_SETTLEMENT == self.battleState) {
return;
}
//console.log(`Received peer inputFrameUpsync batch w/ inputFrameId in [${batch[0].inputFrameId}, ${batch[batch.length - 1].inputFrameId}] for prediction assistance`);
for (let k in batch) {
const inputFrameDownsync = batch[k];
const inputFrameDownsyncId = inputFrameDownsync.inputFrameId;
if (inputFrameDownsyncId <= self.lastAllConfirmedInputFrameId) {
continue;
}
self.getOrPrefabInputFrameUpsync(inputFrameDownsyncId); // Make sure that inputFrame exists locally
const existingInputFrame = self.recentInputCache.GetByFrameId(inputFrameDownsyncId);
existingInputFrame.InputList[peerJoinIndex - 1] = inputFrameDownsync.inputList[peerJoinIndex - 1]; // No need to change "confirmedList", leave it to "onInputFrameDownsyncBatch" -- we're just helping prediction here
self.recentInputCache.SetByFrameId(existingInputFrame, inputFrameDownsyncId);
}
},
onPlayerAdded(rdf /* pb.RoomDownsyncFrame */ ) {
const self = this;
// Update the "finding player" GUI and show it if not previously present
@@ -908,12 +938,13 @@ batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inpu
update(dt) {
const self = this;
if (ALL_BATTLE_STATES.IN_BATTLE == self.battleState) {
const elapsedMillisSinceLastFrameIdTriggered = performance.now() - self.lastRenderFrameIdTriggeredAt;
if (elapsedMillisSinceLastFrameIdTriggered < self.tooFastDtIntervalMillis) {
// [WARNING] We should avoid a frontend ticking too fast to prevent cheating, as well as ticking too slow to cause a "resync avalanche" that impacts user experience!
// console.debug("Avoiding too fast frame@renderFrameId=", self.renderFrameId, ": elapsedMillisSinceLastFrameIdTriggered=", elapsedMillisSinceLastFrameIdTriggered);
return;
}
/*
[WARNING] Different devices might differ in the rate of calling "update(dt)", and the game engine is responsible of keeping this rate statistically constant.
Significantly different rates of calling "update(dt)" among players in a same battle would result in frequent [type#1 forceConfirmation], if you have any doubt on troubles caused by this, sample the FPS curve from all players in that battle.
Kindly note that Significantly different network bandwidths or delay fluctuations would result in frequent [type#1 forceConfirmation] too, but CAUSE FROM DIFFERENT LOCAL "update(dt)" RATE SHOULD BE THE FIRST TO INVESTIGATE AND ELIMINATE -- because we have control on it, but no one has control on the internet.
*/
try {
let st = performance.now();
const noDelayInputFrameId = gopkgs.ConvertToNoDelayInputFrameId(self.renderFrameId);

View File

@@ -11,6 +11,8 @@ cc.Class({
},
onLoad() {
cc.view.setOrientation(cc.macro.ORIENTATION_LANDSCAPE);
cc.view.enableAutoFullScreen(true);
const self = this;
window.mapIns = self;
self.showCriticalCoordinateLabels = false;
@@ -154,7 +156,7 @@ cc.Class({
if (elapsedMillisSinceLastFrameIdTriggered < self.tooFastDtIntervalMillis) {
// [WARNING] We should avoid a frontend ticking too fast to prevent cheating, as well as ticking too slow to cause a "resync avalanche" that impacts user experience!
// console.debug("Avoiding too fast frame@renderFrameId=", self.renderFrameId, ": elapsedMillisSinceLastFrameIdTriggered=", elapsedMillisSinceLastFrameIdTriggered);
return;
//return;
}
try {
let st = performance.now();

View File

@@ -11,14 +11,6 @@ cc.Class({
type: cc.Object,
default: null
},
myAvatarNode: {
type: cc.Node,
default: null,
},
myNameNode: {
type: cc.Node,
default: null,
},
rankingNodes: {
type: [cc.Node],
default: [],
@@ -46,22 +38,6 @@ cc.Class({
showPlayerInfo(playerRichInfoDict) {
this.showRanking(playerRichInfoDict);
this.showMyAvatar();
this.showMyName();
},
showMyName() {
const selfPlayerInfo = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
let name = 'No name';
if (null == selfPlayerInfo.displayName || "" == selfPlayerInfo.displayName) {
name = selfPlayerInfo.name;
} else {
name = selfPlayerInfo.displayName;
}
if (!this.myNameNode) return;
const myNameNodeLabel = this.myNameNode.getComponent(cc.Label);
if (!myNameNodeLabel || null == name) return;
myNameNodeLabel.string = name;
},
showRanking(playerRichInfoDict) {
@@ -115,42 +91,6 @@ cc.Class({
}
},
showMyAvatar() {
const self = this;
const selfPlayerInfo = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
let remoteUrl = selfPlayerInfo.avatar;
if (remoteUrl == null || remoteUrl == '') {
cc.log(`No avatar to show for myself, check storage.`);
return;
} else {
cc.loader.load({
url: remoteUrl,
type: 'jpg'
}, function(err, texture) {
if (err != null || texture == null) {
console.log(err);
} else {
const sf = new cc.SpriteFrame();
sf.setTexture(texture);
self.myAvatarNode.getComponent(cc.Sprite).spriteFrame = sf;
}
});
}
},
showRibbon(winnerInfo, ribbonNode) {
const selfPlayerInfo = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
const texture = (selfPlayerInfo.playerId == winnerInfo.id) ? "textures/resultPanel/WinRibbon" : "textures/resultPanel/loseRibbon";
cc.loader.loadRes(texture, cc.SpriteFrame, function(err, spriteFrame) {
if (err) {
console.log(err);
return;
}
ribbonNode.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});
},
onClose(evt) {
if (this.node.parent) {
this.node.parent.removeChild(this.node);

View File

@@ -169,30 +169,24 @@ cc.Class({
if (self.btnA) {
self.btnA.on(cc.Node.EventType.TOUCH_START, function(evt) {
self._triggerEdgeBtnA(true);
evt.target.runAction(cc.scaleTo(0.1, 0.3));
});
self.btnA.on(cc.Node.EventType.TOUCH_END, function(evt) {
self._triggerEdgeBtnA(false);
evt.target.runAction(cc.scaleTo(0.1, 1.0));
});
self.btnA.on(cc.Node.EventType.TOUCH_CANCEL, function(evt) {
self._triggerEdgeBtnA(false);
evt.target.runAction(cc.scaleTo(0.1, 1.0));
});
}
if (self.btnB) {
self.btnB.on(cc.Node.EventType.TOUCH_START, function(evt) {
self._triggerEdgeBtnB(true);
evt.target.runAction(cc.scaleTo(0.1, 0.3));
});
self.btnB.on(cc.Node.EventType.TOUCH_END, function(evt) {
self._triggerEdgeBtnB(false);
evt.target.runAction(cc.scaleTo(0.1, 1.0));
});
self.btnB.on(cc.Node.EventType.TOUCH_CANCEL, function(evt) {
self._triggerEdgeBtnB(false);
evt.target.runAction(cc.scaleTo(0.1, 1.0));
});
}
@@ -500,13 +494,23 @@ cc.Class({
this.cachedBtnALevel = this.realtimeBtnALevel;
this.btnAEdgeTriggerLock = true;
}
if (rising) {
this.btnA.runAction(cc.scaleTo(0.1, 0.3));
} else {
this.btnA.runAction(cc.scaleTo(0.1, 0.5));
}
},
_triggerEdgeBtnB(rising) {
_triggerEdgeBtnB(rising, evt) {
this.realtimeBtnBLevel = (rising ? 1 : 0);
if (!this.btnBEdgeTriggerLock && (1 - this.realtimeBtnBLevel) == this.cachedBtnBLevel) {
this.cachedBtnBLevel = this.realtimeBtnBLevel;
this.btnBEdgeTriggerLock = true;
}
if (rising) {
this.btnB.runAction(cc.scaleTo(0.1, 0.3));
} else {
this.btnB.runAction(cc.scaleTo(0.1, 0.5));
}
},
});

View File

@@ -11,6 +11,7 @@ window.DOWNSYNC_MSG_ACT_HB_REQ = 1;
window.DOWNSYNC_MSG_ACT_INPUT_BATCH = 2;
window.DOWNSYNC_MSG_ACT_BATTLE_STOPPED = 3;
window.DOWNSYNC_MSG_ACT_FORCED_RESYNC = 4;
window.DOWNSYNC_MSG_ACT_PEER_INPUT_BATCH = 5;
window.sendSafely = function(msgStr) {
/**
@@ -65,6 +66,7 @@ window.handleHbRequirements = function(resp) {
}
if (window.handleBattleColliderInfo) {
window.initSecondarySession(null, window.boundRoomId);
window.handleBattleColliderInfo(resp.bciFrame);
}
};
@@ -130,8 +132,6 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
}
}
const currentHistoryState = window.history && window.history.state ? window.history.state : {};
const clientSession = new WebSocket(urlToConnect);
clientSession.binaryType = 'arraybuffer'; // Make 'event.data' of 'onmessage' an "ArrayBuffer" instead of a "Blob"
@@ -240,3 +240,56 @@ window.clearLocalStorageAndBackToLoginScene = function(shouldRetainBoundRoomIdIn
cc.director.loadScene('login');
};
// For secondary ws session
window.initSecondarySession = function(onopenCb, boundRoomId) {
if (window.secondarySession && window.secondarySession.readyState == WebSocket.OPEN) {
if (null != onopenCb) {
onopenCb();
}
return;
}
const selfPlayerStr = cc.sys.localStorage.getItem("selfPlayer");
const selfPlayer = null == selfPlayerStr ? null : JSON.parse(selfPlayerStr);
const intAuthToken = null == selfPlayer ? "" : selfPlayer.intAuthToken;
let urlToConnect = backendAddress.PROTOCOL.replace('http', 'ws') + '://' + backendAddress.HOST + ":" + backendAddress.PORT + "/tsrhtSecondary?isSecondary=true&intAuthToken=" + intAuthToken + "&boundRoomId=" + boundRoomId;
const clientSession = new WebSocket(urlToConnect);
clientSession.binaryType = 'arraybuffer'; // Make 'event.data' of 'onmessage' an "ArrayBuffer" instead of a "Blob"
clientSession.onopen = function(evt) {
console.warn("The secondary WS clientSession is opened.");
window.secondarySession = clientSession;
if (null == onopenCb) return;
onopenCb();
};
clientSession.onmessage = function(evt) {
if (null == evt || null == evt.data) {
return;
}
try {
const resp = window.pb.protos.WsResp.decode(new Uint8Array(evt.data));
//console.log(`Got non-empty onmessage decoded: resp.act=${resp.act}`);
switch (resp.act) {
case window.DOWNSYNC_MSG_ACT_PEER_INPUT_BATCH:
mapIns.onPeerInputFrameUpsync(resp.peerJoinIndex, resp.inputFrameDownsyncBatch);
break;
default:
break;
}
} catch (e) {
console.error("Secondary ws session, unexpected error when parsing data of:", evt.data, e);
}
};
clientSession.onerror = function(evt) {
console.error("Secondary ws session, error caught on the WS clientSession: ", evt);
};
clientSession.onclose = function(evt) {
// [WARNING] The callback "onclose" might be called AFTER the webpage is refreshed with "1001 == evt.code".
console.warn(`Secondary ws session is closed: evt=${JSON.stringify(evt)}, evt.code=${evt.code}`);
};
};

View File

@@ -1219,6 +1219,7 @@ $root.protos = (function() {
* @property {boolean|null} [onWall] PlayerDownsync onWall
* @property {number|null} [onWallNormX] PlayerDownsync onWallNormX
* @property {number|null} [onWallNormY] PlayerDownsync onWallNormY
* @property {boolean|null} [capturedByInertia] PlayerDownsync capturedByInertia
* @property {string|null} [name] PlayerDownsync name
* @property {string|null} [displayName] PlayerDownsync displayName
* @property {string|null} [avatar] PlayerDownsync avatar
@@ -1463,6 +1464,14 @@ $root.protos = (function() {
*/
PlayerDownsync.prototype.onWallNormY = 0;
/**
* PlayerDownsync capturedByInertia.
* @member {boolean} capturedByInertia
* @memberof protos.PlayerDownsync
* @instance
*/
PlayerDownsync.prototype.capturedByInertia = false;
/**
* PlayerDownsync name.
* @member {string} name
@@ -1567,6 +1576,8 @@ $root.protos = (function() {
writer.uint32(/* id 27, wireType 0 =*/216).int32(message.onWallNormX);
if (message.onWallNormY != null && Object.hasOwnProperty.call(message, "onWallNormY"))
writer.uint32(/* id 28, wireType 0 =*/224).int32(message.onWallNormY);
if (message.capturedByInertia != null && Object.hasOwnProperty.call(message, "capturedByInertia"))
writer.uint32(/* id 29, wireType 0 =*/232).bool(message.capturedByInertia);
if (message.name != null && Object.hasOwnProperty.call(message, "name"))
writer.uint32(/* id 997, wireType 2 =*/7978).string(message.name);
if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName"))
@@ -1719,6 +1730,10 @@ $root.protos = (function() {
message.onWallNormY = reader.int32();
break;
}
case 29: {
message.capturedByInertia = reader.bool();
break;
}
case 997: {
message.name = reader.string();
break;
@@ -1850,6 +1865,9 @@ $root.protos = (function() {
if (message.onWallNormY != null && message.hasOwnProperty("onWallNormY"))
if (!$util.isInteger(message.onWallNormY))
return "onWallNormY: integer expected";
if (message.capturedByInertia != null && message.hasOwnProperty("capturedByInertia"))
if (typeof message.capturedByInertia !== "boolean")
return "capturedByInertia: boolean expected";
if (message.name != null && message.hasOwnProperty("name"))
if (!$util.isString(message.name))
return "name: string expected";
@@ -1930,6 +1948,8 @@ $root.protos = (function() {
message.onWallNormX = object.onWallNormX | 0;
if (object.onWallNormY != null)
message.onWallNormY = object.onWallNormY | 0;
if (object.capturedByInertia != null)
message.capturedByInertia = Boolean(object.capturedByInertia);
if (object.name != null)
message.name = String(object.name);
if (object.displayName != null)
@@ -1981,6 +2001,7 @@ $root.protos = (function() {
object.onWall = false;
object.onWallNormX = 0;
object.onWallNormY = 0;
object.capturedByInertia = false;
object.name = "";
object.displayName = "";
object.avatar = "";
@@ -2041,6 +2062,8 @@ $root.protos = (function() {
object.onWallNormX = message.onWallNormX;
if (message.onWallNormY != null && message.hasOwnProperty("onWallNormY"))
object.onWallNormY = message.onWallNormY;
if (message.capturedByInertia != null && message.hasOwnProperty("capturedByInertia"))
object.capturedByInertia = message.capturedByInertia;
if (message.name != null && message.hasOwnProperty("name"))
object.name = message.name;
if (message.displayName != null && message.hasOwnProperty("displayName"))
@@ -2360,6 +2383,7 @@ $root.protos = (function() {
* @interface IInputFrameUpsync
* @property {number|null} [inputFrameId] InputFrameUpsync inputFrameId
* @property {number|Long|null} [encoded] InputFrameUpsync encoded
* @property {number|null} [joinIndex] InputFrameUpsync joinIndex
*/
/**
@@ -2393,6 +2417,14 @@ $root.protos = (function() {
*/
InputFrameUpsync.prototype.encoded = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
/**
* InputFrameUpsync joinIndex.
* @member {number} joinIndex
* @memberof protos.InputFrameUpsync
* @instance
*/
InputFrameUpsync.prototype.joinIndex = 0;
/**
* Creates a new InputFrameUpsync instance using the specified properties.
* @function create
@@ -2421,6 +2453,8 @@ $root.protos = (function() {
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.inputFrameId);
if (message.encoded != null && Object.hasOwnProperty.call(message, "encoded"))
writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.encoded);
if (message.joinIndex != null && Object.hasOwnProperty.call(message, "joinIndex"))
writer.uint32(/* id 3, wireType 0 =*/24).int32(message.joinIndex);
return writer;
};
@@ -2463,6 +2497,10 @@ $root.protos = (function() {
message.encoded = reader.uint64();
break;
}
case 3: {
message.joinIndex = reader.int32();
break;
}
default:
reader.skipType(tag & 7);
break;
@@ -2504,6 +2542,9 @@ $root.protos = (function() {
if (message.encoded != null && message.hasOwnProperty("encoded"))
if (!$util.isInteger(message.encoded) && !(message.encoded && $util.isInteger(message.encoded.low) && $util.isInteger(message.encoded.high)))
return "encoded: integer|Long expected";
if (message.joinIndex != null && message.hasOwnProperty("joinIndex"))
if (!$util.isInteger(message.joinIndex))
return "joinIndex: integer expected";
return null;
};
@@ -2530,6 +2571,8 @@ $root.protos = (function() {
message.encoded = object.encoded;
else if (typeof object.encoded === "object")
message.encoded = new $util.LongBits(object.encoded.low >>> 0, object.encoded.high >>> 0).toNumber(true);
if (object.joinIndex != null)
message.joinIndex = object.joinIndex | 0;
return message;
};
@@ -2553,6 +2596,7 @@ $root.protos = (function() {
object.encoded = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.encoded = options.longs === String ? "0" : 0;
object.joinIndex = 0;
}
if (message.inputFrameId != null && message.hasOwnProperty("inputFrameId"))
object.inputFrameId = message.inputFrameId;
@@ -2561,6 +2605,8 @@ $root.protos = (function() {
object.encoded = options.longs === String ? String(message.encoded) : message.encoded;
else
object.encoded = options.longs === String ? $util.Long.prototype.toString.call(message.encoded) : options.longs === Number ? new $util.LongBits(message.encoded.low >>> 0, message.encoded.high >>> 0).toNumber(true) : message.encoded;
if (message.joinIndex != null && message.hasOwnProperty("joinIndex"))
object.joinIndex = message.joinIndex;
return object;
};
@@ -3513,6 +3559,7 @@ $root.protos = (function() {
* @property {protos.RoomDownsyncFrame|null} [rdf] WsResp rdf
* @property {Array.<protos.InputFrameDownsync>|null} [inputFrameDownsyncBatch] WsResp inputFrameDownsyncBatch
* @property {protos.BattleColliderInfo|null} [bciFrame] WsResp bciFrame
* @property {number|null} [peerJoinIndex] WsResp peerJoinIndex
*/
/**
@@ -3579,6 +3626,14 @@ $root.protos = (function() {
*/
WsResp.prototype.bciFrame = null;
/**
* WsResp peerJoinIndex.
* @member {number} peerJoinIndex
* @memberof protos.WsResp
* @instance
*/
WsResp.prototype.peerJoinIndex = 0;
/**
* Creates a new WsResp instance using the specified properties.
* @function create
@@ -3616,6 +3671,8 @@ $root.protos = (function() {
$root.protos.InputFrameDownsync.encode(message.inputFrameDownsyncBatch[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
if (message.bciFrame != null && Object.hasOwnProperty.call(message, "bciFrame"))
$root.protos.BattleColliderInfo.encode(message.bciFrame, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
if (message.peerJoinIndex != null && Object.hasOwnProperty.call(message, "peerJoinIndex"))
writer.uint32(/* id 7, wireType 0 =*/56).int32(message.peerJoinIndex);
return writer;
};
@@ -3676,6 +3733,10 @@ $root.protos = (function() {
message.bciFrame = $root.protos.BattleColliderInfo.decode(reader, reader.uint32());
break;
}
case 7: {
message.peerJoinIndex = reader.int32();
break;
}
default:
reader.skipType(tag & 7);
break;
@@ -3739,6 +3800,9 @@ $root.protos = (function() {
if (error)
return "bciFrame." + error;
}
if (message.peerJoinIndex != null && message.hasOwnProperty("peerJoinIndex"))
if (!$util.isInteger(message.peerJoinIndex))
return "peerJoinIndex: integer expected";
return null;
};
@@ -3780,6 +3844,8 @@ $root.protos = (function() {
throw TypeError(".protos.WsResp.bciFrame: object expected");
message.bciFrame = $root.protos.BattleColliderInfo.fromObject(object.bciFrame);
}
if (object.peerJoinIndex != null)
message.peerJoinIndex = object.peerJoinIndex | 0;
return message;
};
@@ -3804,6 +3870,7 @@ $root.protos = (function() {
object.act = 0;
object.rdf = null;
object.bciFrame = null;
object.peerJoinIndex = 0;
}
if (message.ret != null && message.hasOwnProperty("ret"))
object.ret = message.ret;
@@ -3820,6 +3887,8 @@ $root.protos = (function() {
}
if (message.bciFrame != null && message.hasOwnProperty("bciFrame"))
object.bciFrame = $root.protos.BattleColliderInfo.toObject(message.bciFrame, options);
if (message.peerJoinIndex != null && message.hasOwnProperty("peerJoinIndex"))
object.peerJoinIndex = message.peerJoinIndex;
return object;
};
@@ -3862,6 +3931,7 @@ $root.protos = (function() {
* @property {number|Long|null} [unconfirmedMask] InputsBufferSnapshot unconfirmedMask
* @property {Array.<protos.InputFrameDownsync>|null} [toSendInputFrameDownsyncs] InputsBufferSnapshot toSendInputFrameDownsyncs
* @property {boolean|null} [shouldForceResync] InputsBufferSnapshot shouldForceResync
* @property {number|null} [peerJoinIndex] InputsBufferSnapshot peerJoinIndex
*/
/**
@@ -3912,6 +3982,14 @@ $root.protos = (function() {
*/
InputsBufferSnapshot.prototype.shouldForceResync = false;
/**
* InputsBufferSnapshot peerJoinIndex.
* @member {number} peerJoinIndex
* @memberof protos.InputsBufferSnapshot
* @instance
*/
InputsBufferSnapshot.prototype.peerJoinIndex = 0;
/**
* Creates a new InputsBufferSnapshot instance using the specified properties.
* @function create
@@ -3945,6 +4023,8 @@ $root.protos = (function() {
$root.protos.InputFrameDownsync.encode(message.toSendInputFrameDownsyncs[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
if (message.shouldForceResync != null && Object.hasOwnProperty.call(message, "shouldForceResync"))
writer.uint32(/* id 4, wireType 0 =*/32).bool(message.shouldForceResync);
if (message.peerJoinIndex != null && Object.hasOwnProperty.call(message, "peerJoinIndex"))
writer.uint32(/* id 5, wireType 0 =*/40).int32(message.peerJoinIndex);
return writer;
};
@@ -3997,6 +4077,10 @@ $root.protos = (function() {
message.shouldForceResync = reader.bool();
break;
}
case 5: {
message.peerJoinIndex = reader.int32();
break;
}
default:
reader.skipType(tag & 7);
break;
@@ -4050,6 +4134,9 @@ $root.protos = (function() {
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
if (typeof message.shouldForceResync !== "boolean")
return "shouldForceResync: boolean expected";
if (message.peerJoinIndex != null && message.hasOwnProperty("peerJoinIndex"))
if (!$util.isInteger(message.peerJoinIndex))
return "peerJoinIndex: integer expected";
return null;
};
@@ -4088,6 +4175,8 @@ $root.protos = (function() {
}
if (object.shouldForceResync != null)
message.shouldForceResync = Boolean(object.shouldForceResync);
if (object.peerJoinIndex != null)
message.peerJoinIndex = object.peerJoinIndex | 0;
return message;
};
@@ -4114,6 +4203,7 @@ $root.protos = (function() {
} else
object.unconfirmedMask = options.longs === String ? "0" : 0;
object.shouldForceResync = false;
object.peerJoinIndex = 0;
}
if (message.refRenderFrameId != null && message.hasOwnProperty("refRenderFrameId"))
object.refRenderFrameId = message.refRenderFrameId;
@@ -4129,6 +4219,8 @@ $root.protos = (function() {
}
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
object.shouldForceResync = message.shouldForceResync;
if (message.peerJoinIndex != null && message.hasOwnProperty("peerJoinIndex"))
object.peerJoinIndex = message.peerJoinIndex;
return object;
};

View File

@@ -6,16 +6,22 @@ all: help
GOPROXY=https://goproxy.io
serve:
gopherjs clean
gopherjs serve $(PROJECTNAME)
build:
gopherjs build $(PROJECTNAME)
rm ../frontend/assets/plugin_scripts/jsexport.js && mv ./jsexport.js ../frontend/assets/plugin_scripts/jsexport.js
clean:
gopherjs clean
rm -f ../frontend/assets/plugin_scripts/jsexport.js
#rm -f ../frontend/assets/plugin_scripts/jsexport.js.map
build-min:
build: clean
gopherjs build $(PROJECTNAME)
mv ./jsexport.js ../frontend/assets/plugin_scripts/
#mv ./jsexport.js.map ../frontend/assets/plugin_scripts/
build-min: clean
gopherjs build -m $(PROJECTNAME)
rm ../frontend/assets/plugin_scripts/jsexport.js && mv ./jsexport.js ../frontend/assets/plugin_scripts/jsexport.js
mv ./jsexport.js ../frontend/assets/plugin_scripts/
#mv ./jsexport.js.map ../frontend/assets/plugin_scripts/
.PHONY: help

View File

@@ -22,7 +22,7 @@ const (
GRAVITY_X = int32(0)
GRAVITY_Y = -int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO) // makes all "playerCollider.Y" a multiple of 0.5 in all cases
INPUT_DELAY_FRAMES = int32(4) // in the count of render frames
INPUT_DELAY_FRAMES = int32(8) // in the count of render frames
INPUT_SCALE_FRAMES = uint32(2) // inputDelayedAndScaledFrameId = ((originalFrameId - InputDelayFrames) >> InputScaleFrames)
NST_DELAY_FRAMES = int32(16) // network-single-trip delay in the count of render frames, proposed to be (InputDelayFrames >> 1) because we expect a round-trip delay to be exactly "InputDelayFrames"
@@ -77,6 +77,8 @@ const (
ATK_CHARACTER_STATE_DASHING = int32(15)
ATK_CHARACTER_STATE_ONWALL = int32(16)
ATK_CHARACTER_STATE_TURNAROUND = int32(17)
)
var inAirSet = map[int32]bool{
@@ -489,19 +491,19 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
}
patternId := PATTERN_ID_NO_OP
if 0 < decodedInput.BtnALevel {
if decodedInput.BtnALevel > prevBtnALevel {
if 0 > effDy {
patternId = 3
} else if 0 < effDy {
patternId = 2
} else {
patternId = 1
}
} else {
patternId = 4 // Holding
}
}
if 0 < decodedInput.BtnALevel {
if decodedInput.BtnALevel > prevBtnALevel {
if 0 > effDy {
patternId = 3
} else if 0 < effDy {
patternId = 2
} else {
patternId = 1
}
} else {
patternId = 4 // Holding
}
}
return patternId, jumpedOrNot, effDx, effDy
}
@@ -514,31 +516,32 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
// Make a copy first
for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
nextRenderFramePlayers[i] = &PlayerDownsync{
Id: currPlayerDownsync.Id,
VirtualGridX: currPlayerDownsync.VirtualGridX,
VirtualGridY: currPlayerDownsync.VirtualGridY,
DirX: currPlayerDownsync.DirX,
DirY: currPlayerDownsync.DirY,
VelX: currPlayerDownsync.VelX,
VelY: currPlayerDownsync.VelY,
CharacterState: currPlayerDownsync.CharacterState,
InAir: true,
OnWall: false,
Speed: currPlayerDownsync.Speed,
BattleState: currPlayerDownsync.BattleState,
Score: currPlayerDownsync.Score,
Removed: currPlayerDownsync.Removed,
JoinIndex: currPlayerDownsync.JoinIndex,
Hp: currPlayerDownsync.Hp,
MaxHp: currPlayerDownsync.MaxHp,
FramesToRecover: currPlayerDownsync.FramesToRecover - 1,
FramesInChState: currPlayerDownsync.FramesInChState + 1,
ActiveSkillId: currPlayerDownsync.ActiveSkillId,
ActiveSkillHit: currPlayerDownsync.ActiveSkillHit,
FramesInvinsible: currPlayerDownsync.FramesInvinsible - 1,
ColliderRadius: currPlayerDownsync.ColliderRadius,
OnWallNormX: currPlayerDownsync.OnWallNormX,
OnWallNormY: currPlayerDownsync.OnWallNormY,
Id: currPlayerDownsync.Id,
VirtualGridX: currPlayerDownsync.VirtualGridX,
VirtualGridY: currPlayerDownsync.VirtualGridY,
DirX: currPlayerDownsync.DirX,
DirY: currPlayerDownsync.DirY,
VelX: currPlayerDownsync.VelX,
VelY: currPlayerDownsync.VelY,
CharacterState: currPlayerDownsync.CharacterState,
InAir: true,
OnWall: false,
Speed: currPlayerDownsync.Speed,
BattleState: currPlayerDownsync.BattleState,
Score: currPlayerDownsync.Score,
Removed: currPlayerDownsync.Removed,
JoinIndex: currPlayerDownsync.JoinIndex,
Hp: currPlayerDownsync.Hp,
MaxHp: currPlayerDownsync.MaxHp,
FramesToRecover: currPlayerDownsync.FramesToRecover - 1,
FramesInChState: currPlayerDownsync.FramesInChState + 1,
ActiveSkillId: currPlayerDownsync.ActiveSkillId,
ActiveSkillHit: currPlayerDownsync.ActiveSkillHit,
FramesInvinsible: currPlayerDownsync.FramesInvinsible - 1,
ColliderRadius: currPlayerDownsync.ColliderRadius,
OnWallNormX: currPlayerDownsync.OnWallNormX,
OnWallNormY: currPlayerDownsync.OnWallNormY,
CapturedByInertia: currPlayerDownsync.CapturedByInertia,
}
if nextRenderFramePlayers[i].FramesToRecover < 0 {
nextRenderFramePlayers[i].FramesToRecover = 0
@@ -631,24 +634,54 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
}
if 0 == currPlayerDownsync.FramesToRecover {
if 0 != effDx {
xfac := int32(1)
if 0 > effDx {
xfac = -xfac
}
thatPlayerInNextFrame.DirX = effDx
thatPlayerInNextFrame.DirY = effDy
thatPlayerInNextFrame.VelX = xfac * currPlayerDownsync.Speed
if intAbs(thatPlayerInNextFrame.VelX) < intAbs(currPlayerDownsync.VelX) {
// Wall jumping
thatPlayerInNextFrame.VelX = xfac * intAbs(currPlayerDownsync.VelX)
}
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_WALKING
} else {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
thatPlayerInNextFrame.VelX = 0
prevCapturedByInertia := currPlayerDownsync.CapturedByInertia
isWallJumping := (currPlayerDownsync.Speed < intAbs(currPlayerDownsync.VelX))
/*
if isWallJumping {
fmt.Printf("joinIndex=%d is wall jumping\n{renderFrame.id: %d, currPlayerDownsync.Speed: %d, currPlayerDownsync.VelX: %d}\n", currPlayerDownsync.JoinIndex, currRenderFrame.Id, currPlayerDownsync.Speed, currPlayerDownsync.VelX)
}
*/
alignedWithInertia := true
if 0 == effDx && 0 != thatPlayerInNextFrame.VelX {
alignedWithInertia = false
} else if 0 != effDx && 0 == thatPlayerInNextFrame.VelX {
alignedWithInertia = false
} else if 0 > effDx*thatPlayerInNextFrame.VelX {
alignedWithInertia = false
}
if !isWallJumping && !prevCapturedByInertia && !alignedWithInertia {
/*
[WARNING] A "turn-around", or in more generic direction schema a "change in direction" is a hurdle for our current "prediction+rollback" approach, yet applying a "FramesToRecover" for "turn-around" can alleviate the graphical inconsistence to a huge extent! For better operational experience, this is intentionally NOT APPLIED TO WALL JUMPING!
When "false == alignedWithInertia", we're GUARANTEED TO BE WRONG AT INPUT PREDICTION ON THE FRONTEND, but we COULD STILL BE RIGHT AT POSITION PREDICTION WITHIN "InertiaFramesToRecover" -- which together with "INPUT_DELAY_FRAMES" grants the frontend a big chance to be graphically consistent even upon wrong prediction!
*/
//fmt.Printf("joinIndex=%d is not wall jumping and not aligned w/ inertia\n{renderFrame.id: %d, effDx: %d, thatPlayerInNextFrame.VelX: %d}\n", currPlayerDownsync.JoinIndex, currRenderFrame.Id, effDx, thatPlayerInNextFrame.VelX)
thatPlayerInNextFrame.CapturedByInertia = true
thatPlayerInNextFrame.FramesToRecover = chConfig.InertiaFramesToRecover
} else {
thatPlayerInNextFrame.CapturedByInertia = false
if 0 != effDx {
xfac := int32(1)
if 0 > effDx {
xfac = -xfac
}
thatPlayerInNextFrame.DirX = effDx
thatPlayerInNextFrame.DirY = effDy
if isWallJumping {
//fmt.Printf("joinIndex=%d is controlling while wall jumping\n{renderFrame.id: %d, currPlayerDownsync.Speed: %d, currPlayerDownsync.VelX: %d, effDx: %d}\n", currPlayerDownsync.JoinIndex, currRenderFrame.Id, currPlayerDownsync.Speed, currPlayerDownsync.VelX, effDx)
thatPlayerInNextFrame.VelX = xfac * intAbs(currPlayerDownsync.VelX)
} else {
thatPlayerInNextFrame.VelX = xfac * currPlayerDownsync.Speed
}
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_WALKING
} else {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
thatPlayerInNextFrame.VelX = 0
}
}
}
}

View File

@@ -15,8 +15,9 @@ type CharacterConfig struct {
GetUpInvinsibleFrames int32
GetUpFramesToRecover int32
Speed int32
JumpingInitVelY int32
Speed int32
JumpingInitVelY int32
JumpingFramesToRecover int32 // Not used yet
DashingEnabled bool
OnWallEnabled bool
@@ -25,6 +26,8 @@ type CharacterConfig struct {
WallJumpingInitVelY int32
WallSlidingVelY int32
InertiaFramesToRecover int32
SkillMapper SkillMapperType
}
@@ -42,8 +45,11 @@ var Characters = map[int]*CharacterConfig{
GetUpInvinsibleFrames: int32(10),
GetUpFramesToRecover: int32(27),
Speed: int32(float64(3.0) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
Speed: int32(float64(2.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingFramesToRecover: int32(2),
InertiaFramesToRecover: int32(5),
DashingEnabled: false,
OnWallEnabled: false,
@@ -88,13 +94,16 @@ var Characters = map[int]*CharacterConfig{
GetUpInvinsibleFrames: int32(10),
GetUpFramesToRecover: int32(27),
Speed: int32(float64(4.0) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(7.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
Speed: int32(float64(2.6) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(7.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingFramesToRecover: int32(2),
InertiaFramesToRecover: int32(5),
DashingEnabled: true,
OnWallEnabled: true,
WallJumpingFramesToRecover: int32(9), // 8 would be the minimum for an avg human
WallJumpingInitVelX: int32(float64(2.5) * WORLD_TO_VIRTUAL_GRID_RATIO), // Default is "appeared facing right", but actually holding ctrl against left
WallJumpingFramesToRecover: int32(8), // 8 would be the minimum for an avg human
WallJumpingInitVelX: int32(float64(2.8) * WORLD_TO_VIRTUAL_GRID_RATIO), // Default is "appeared facing right", but actually holding ctrl against left
WallJumpingInitVelY: int32(float64(7) * WORLD_TO_VIRTUAL_GRID_RATIO),
WallSlidingVelY: int32(float64(-1) * WORLD_TO_VIRTUAL_GRID_RATIO),
@@ -138,8 +147,11 @@ var Characters = map[int]*CharacterConfig{
GetUpInvinsibleFrames: int32(8),
GetUpFramesToRecover: int32(30),
Speed: int32(float64(3.0) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(7.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
Speed: int32(float64(2.0) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(7.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingFramesToRecover: int32(2),
InertiaFramesToRecover: int32(5),
DashingEnabled: false,
OnWallEnabled: false,
@@ -302,7 +314,7 @@ var skills = map[int]*Skill{
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
CancellableStFrame: int32(8),
CancellableStFrame: int32(13),
CancellableEdFrame: int32(30),
CancelTransit: map[int]int{
@@ -337,7 +349,7 @@ var skills = map[int]*Skill{
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
CancellableStFrame: int32(19),
CancellableStFrame: int32(23),
CancellableEdFrame: int32(36),
CancelTransit: map[int]int{
1: 6,

View File

@@ -37,6 +37,8 @@ type PlayerDownsync struct {
OnWallNormX int32
OnWallNormY int32
CapturedByInertia bool
ActiveSkillId int32
ActiveSkillHit int32

View File

@@ -42,7 +42,7 @@ func NewBarrierJs(boundary *Polygon2D) *js.Object {
})
}
func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, activeSkillId, activeSkillHit, framesInvinsible, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius int32, inAir, onWall bool, onWallNormX, onWallNormY, bulletTeamId, chCollisionTeamId int32) *js.Object {
func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, activeSkillId, activeSkillHit, framesInvinsible, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius int32, inAir, onWall bool, onWallNormX, onWallNormY int32, capturedByInertia bool, bulletTeamId, chCollisionTeamId int32) *js.Object {
return js.MakeWrapper(&PlayerDownsync{
Id: id,
VirtualGridX: virtualGridX,
@@ -67,6 +67,7 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY,
OnWall: onWall,
OnWallNormX: onWallNormX,
OnWallNormY: onWallNormY,
CapturedByInertia: capturedByInertia,
BulletTeamId: bulletTeamId,
ChCollisionTeamId: chCollisionTeamId,
})

View File

@@ -66,4 +66,21 @@ hp application/json application/javascript;
proxy_pass http://tsrht_cluster/tsrht$is_args$args;
}
location ~^/tsrhtSecondary$ {
# Reference http://www.tornadoweb.org/en/stable/guide/running.html
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
# Reverse-proxy for ws connection.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://tsrht_cluster/tsrhtSecondary$is_args$args;
}
}