mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 03:39:00 +00:00
Merge pull request #1 from genxium/manual_collision
Merge the manual collision.
This commit is contained in:
commit
ff092a40ed
11
ConcerningEdgeCases.md
Normal file
11
ConcerningEdgeCases.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
Under the current "input delay" algorithm, the lag of a single player would cause all the other players to receive outdated commands, e.g. when at a certain moment
|
||||||
|
- player#1: renderFrameId = 100, significantly lagged due to local CPU overheated
|
||||||
|
- player#2: renderFrameId = 240
|
||||||
|
- player#3: renderFrameId = 239
|
||||||
|
- player#4: renderFrameId = 242
|
||||||
|
|
||||||
|
players #2, #3 #4 would receive "outdated(in their subjective feelings) but all-confirmed commands" from then on, thus forced to rollback and chase many frames - the lag due to "large range of frame-chasing" would then further deteriorate the situation - like an avalanche.
|
||||||
|
|
||||||
|
In a "no-server & p2p" setup, I couldn't think of a proper way to cope with such edge case. Solely on the frontend we could only mitigate the impact to players #2, #3, #4, e.g. a potential lag due to "large range of frame-chasing" is proactively avoided in `<proj-root>/frontend/assets/scripts/Map.js, function update(dt)`.
|
||||||
|
|
||||||
|
However in a "server as authority" setup, the server could force confirming an inputFrame without player#1's upsync, and notify player#1 to apply a "roomDownsyncFrame" as well as drop all its outdated local inputFrames.
|
@ -1,8 +1,8 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
type RingBuffer struct {
|
type RingBuffer struct {
|
||||||
Ed int32 // write index
|
Ed int32 // write index, open index
|
||||||
St int32 // read index
|
St int32 // read index, closed index
|
||||||
EdFrameId int32
|
EdFrameId int32
|
||||||
StFrameId int32
|
StFrameId int32
|
||||||
N int32
|
N int32
|
||||||
|
@ -3,7 +3,6 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"github.com/ByteArena/box2d"
|
"github.com/ByteArena/box2d"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@ -15,6 +14,7 @@ import (
|
|||||||
. "server/common"
|
. "server/common"
|
||||||
"server/common/utils"
|
"server/common/utils"
|
||||||
pb "server/pb_output"
|
pb "server/pb_output"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -31,8 +31,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MAGIC_REMOVED_AT_FRAME_ID_PERMANENT_REMOVAL_MARGIN = 5
|
MAGIC_ROOM_DOWNSYNC_FRAME_ID_BATTLE_READY_TO_START = -1
|
||||||
MAGIC_ROOM_DOWNSYNC_FRAME_ID_BATTLE_READY_TO_START = -99
|
MAGIC_ROOM_DOWNSYNC_FRAME_ID_BATTLE_START = 0
|
||||||
MAGIC_ROOM_DOWNSYNC_FRAME_ID_PLAYER_ADDED_AND_ACKED = -98
|
MAGIC_ROOM_DOWNSYNC_FRAME_ID_PLAYER_ADDED_AND_ACKED = -98
|
||||||
MAGIC_ROOM_DOWNSYNC_FRAME_ID_PLAYER_READDED_AND_ACKED = -97
|
MAGIC_ROOM_DOWNSYNC_FRAME_ID_PLAYER_READDED_AND_ACKED = -97
|
||||||
|
|
||||||
@ -535,7 +535,7 @@ func (pR *Room) ChooseStage() error {
|
|||||||
ErrFatal(err)
|
ErrFatal(err)
|
||||||
|
|
||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
stageNameList := []string{/*"pacman" ,*/ "richsoil"}
|
stageNameList := []string{ /*"pacman" ,*/ "richsoil"}
|
||||||
chosenStageIndex := rand.Int() % len(stageNameList) // Hardcoded temporarily. -- YFLu
|
chosenStageIndex := rand.Int() % len(stageNameList) // Hardcoded temporarily. -- YFLu
|
||||||
|
|
||||||
pR.StageName = stageNameList[chosenStageIndex]
|
pR.StageName = stageNameList[chosenStageIndex]
|
||||||
@ -701,10 +701,10 @@ func (pR *Room) CanPopSt(refLowerInputFrameId int32) bool {
|
|||||||
|
|
||||||
func (pR *Room) AllPlayerInputsBufferString() string {
|
func (pR *Room) AllPlayerInputsBufferString() string {
|
||||||
s := make([]string, 0)
|
s := make([]string, 0)
|
||||||
s = append(s, fmt.Sprintf("{lastAllConfirmedInputFrameId: %v, lastAllConfirmedInputFrameIdWithChange: %v}", pR.LastAllConfirmedInputFrameId, pR.LastAllConfirmedInputFrameIdWithChange))
|
s = append(s, fmt.Sprintf("{lastAllConfirmedInputFrameId: %v, lastAllConfirmedInputFrameIdWithChange: %v}", pR.LastAllConfirmedInputFrameId, pR.LastAllConfirmedInputFrameIdWithChange))
|
||||||
for playerId, player := range pR.Players {
|
for playerId, player := range pR.Players {
|
||||||
s = append(s, fmt.Sprintf("{playerId: %v, ackingFrameId: %v, ackingInputFrameId: %v, lastSentInputFrameId: %v}", playerId, player.AckingFrameId, player.AckingInputFrameId, player.LastSentInputFrameId))
|
s = append(s, fmt.Sprintf("{playerId: %v, ackingFrameId: %v, ackingInputFrameId: %v, lastSentInputFrameId: %v}", playerId, player.AckingFrameId, player.AckingInputFrameId, player.LastSentInputFrameId))
|
||||||
}
|
}
|
||||||
for i := pR.AllPlayerInputsBuffer.StFrameId; i < pR.AllPlayerInputsBuffer.EdFrameId; i++ {
|
for i := pR.AllPlayerInputsBuffer.StFrameId; i < pR.AllPlayerInputsBuffer.EdFrameId; i++ {
|
||||||
tmp := pR.AllPlayerInputsBuffer.GetByFrameId(i)
|
tmp := pR.AllPlayerInputsBuffer.GetByFrameId(i)
|
||||||
if nil == tmp {
|
if nil == tmp {
|
||||||
@ -736,27 +736,23 @@ func (pR *Room) StartBattle() {
|
|||||||
*/
|
*/
|
||||||
battleMainLoop := func() {
|
battleMainLoop := func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
Logger.Error("battleMainLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("panic", r))
|
Logger.Error("battleMainLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("panic", r))
|
||||||
}
|
}
|
||||||
Logger.Info("The `battleMainLoop` is stopped for:", zap.Any("roomId", pR.Id))
|
Logger.Info("The `battleMainLoop` is stopped for:", zap.Any("roomId", pR.Id))
|
||||||
pR.onBattleStoppedForSettlement()
|
pR.onBattleStoppedForSettlement()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
battleMainLoopStartedNanos := utils.UnixtimeNano()
|
battleMainLoopStartedNanos := utils.UnixtimeNano()
|
||||||
var totalElapsedNanos int64
|
totalElapsedNanos := int64(0)
|
||||||
totalElapsedNanos = 0
|
|
||||||
|
|
||||||
// inputFrameIdDownsyncToleranceFrameCnt := int32(1)
|
|
||||||
|
|
||||||
Logger.Info("The `battleMainLoop` is started for:", zap.Any("roomId", pR.Id))
|
Logger.Info("The `battleMainLoop` is started for:", zap.Any("roomId", pR.Id))
|
||||||
for {
|
for {
|
||||||
pR.Tick++ // It's important to increment "pR.Tick" here such that the "InputFrameDownsync.InputFrameId" is most advanced
|
if 0 == pR.Tick {
|
||||||
if 1 == pR.Tick {
|
|
||||||
// The legacy frontend code needs this "kickoffFrame" to remove the "ready to start 3-2-1" panel
|
// The legacy frontend code needs this "kickoffFrame" to remove the "ready to start 3-2-1" panel
|
||||||
kickoffFrame := pb.RoomDownsyncFrame{
|
kickoffFrame := pb.RoomDownsyncFrame{
|
||||||
Id: pR.Tick,
|
Id: pR.Tick,
|
||||||
RefFrameId: 0, // Hardcoded for now.
|
RefFrameId: MAGIC_ROOM_DOWNSYNC_FRAME_ID_BATTLE_START,
|
||||||
Players: toPbPlayers(pR.Players),
|
Players: toPbPlayers(pR.Players),
|
||||||
Treasures: toPbTreasures(pR.Treasures),
|
Treasures: toPbTreasures(pR.Treasures),
|
||||||
Traps: toPbTraps(pR.Traps),
|
Traps: toPbTraps(pR.Traps),
|
||||||
@ -822,7 +818,6 @@ func (pR *Room) StartBattle() {
|
|||||||
// [WARNING] EDGE CASE HERE: Upon initialization, all of "lastAllConfirmedInputFrameId", "lastAllConfirmedInputFrameIdWithChange" and "anchorInputFrameId" are "-1", thus "candidateToSendInputFrameId" starts with "0", however "inputFrameId: 0" might not have been all confirmed!
|
// [WARNING] EDGE CASE HERE: Upon initialization, all of "lastAllConfirmedInputFrameId", "lastAllConfirmedInputFrameIdWithChange" and "anchorInputFrameId" are "-1", thus "candidateToSendInputFrameId" starts with "0", however "inputFrameId: 0" might not have been all confirmed!
|
||||||
debugSendingInputFrameId := int32(-1)
|
debugSendingInputFrameId := int32(-1)
|
||||||
|
|
||||||
// TODO: If a buffered "inputFrame" is inserted but has been non-all-confirmed for a long time, e.g. inserted at "inputFrameId=42" but still non-all-confirmed at "inputFrameId=980", the server should mark that of "inputFrameId=42" as well as send it to the unconfirmed players with an extra "RoomDownsyncFrame" for their FORCE RESET OF REFERENCE STATE
|
|
||||||
for candidateToSendInputFrameId <= lastAllConfirmedInputFrameIdWithChange {
|
for candidateToSendInputFrameId <= lastAllConfirmedInputFrameIdWithChange {
|
||||||
tmp := pR.AllPlayerInputsBuffer.GetByFrameId(candidateToSendInputFrameId)
|
tmp := pR.AllPlayerInputsBuffer.GetByFrameId(candidateToSendInputFrameId)
|
||||||
if nil == tmp {
|
if nil == tmp {
|
||||||
@ -848,12 +843,7 @@ func (pR *Room) StartBattle() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pR.Tick++
|
||||||
if swapped := atomic.CompareAndSwapInt32(&(pR.LastAllConfirmedInputFrameIdWithChange), lastAllConfirmedInputFrameIdWithChange, -1); !swapped {
|
|
||||||
// "OnBattleCmdReceived" might be updating "pR.LastAllConfirmedInputFrameIdWithChange" simultaneously, don't update here if the old value is no longer valid
|
|
||||||
Logger.Warn("pR.LastAllConfirmedInputFrameIdWithChange NOT UPDATED:", zap.Any("roomId", pR.Id), zap.Any("refInputFrameId", refInputFrameId), zap.Any("StFrameId", pR.AllPlayerInputsBuffer.StFrameId), zap.Any("EdFrameId", pR.AllPlayerInputsBuffer.EdFrameId))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
now := utils.UnixtimeNano()
|
now := utils.UnixtimeNano()
|
||||||
elapsedInCalculation := now - stCalculation
|
elapsedInCalculation := now - stCalculation
|
||||||
totalElapsedNanos = (now - battleMainLoopStartedNanos)
|
totalElapsedNanos = (now - battleMainLoopStartedNanos)
|
||||||
@ -953,10 +943,10 @@ func (pR *Room) OnBattleCmdReceived(pReq *pb.WsReq) {
|
|||||||
Logger.Info("Key inputFrame change", zap.Any("roomId", pR.Id), zap.Any("inputFrameId", clientInputFrameId), zap.Any("lastInputFrameId", pR.LastAllConfirmedInputFrameId), zap.Any("StFrameId", pR.AllPlayerInputsBuffer.StFrameId), zap.Any("EdFrameId", pR.AllPlayerInputsBuffer.EdFrameId), zap.Any("newInputList", inputFrameDownsync.InputList), zap.Any("lastInputList", pR.LastAllConfirmedInputList))
|
Logger.Info("Key inputFrame change", zap.Any("roomId", pR.Id), zap.Any("inputFrameId", clientInputFrameId), zap.Any("lastInputFrameId", pR.LastAllConfirmedInputFrameId), zap.Any("StFrameId", pR.AllPlayerInputsBuffer.StFrameId), zap.Any("EdFrameId", pR.AllPlayerInputsBuffer.EdFrameId), zap.Any("newInputList", inputFrameDownsync.InputList), zap.Any("lastInputList", pR.LastAllConfirmedInputList))
|
||||||
}
|
}
|
||||||
atomic.StoreInt32(&(pR.LastAllConfirmedInputFrameId), clientInputFrameId) // [WARNING] It's IMPORTANT that "pR.LastAllConfirmedInputFrameId" is NOT NECESSARILY CONSECUTIVE, i.e. if one of the players disconnects and reconnects within a considerable amount of frame delays!
|
atomic.StoreInt32(&(pR.LastAllConfirmedInputFrameId), clientInputFrameId) // [WARNING] It's IMPORTANT that "pR.LastAllConfirmedInputFrameId" is NOT NECESSARILY CONSECUTIVE, i.e. if one of the players disconnects and reconnects within a considerable amount of frame delays!
|
||||||
for i,v := range inputFrameDownsync.InputList {
|
for i, v := range inputFrameDownsync.InputList {
|
||||||
// To avoid potential misuse of pointers
|
// To avoid potential misuse of pointers
|
||||||
pR.LastAllConfirmedInputList[i] = v
|
pR.LastAllConfirmedInputList[i] = v
|
||||||
}
|
}
|
||||||
if pR.inputFrameIdDebuggable(clientInputFrameId) {
|
if pR.inputFrameIdDebuggable(clientInputFrameId) {
|
||||||
Logger.Info("inputFrame lifecycle#2[allconfirmed]", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("inputFrameId", clientInputFrameId), zap.Any("StFrameId", pR.AllPlayerInputsBuffer.StFrameId), zap.Any("EdFrameId", pR.AllPlayerInputsBuffer.EdFrameId))
|
Logger.Info("inputFrame lifecycle#2[allconfirmed]", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("inputFrameId", clientInputFrameId), zap.Any("StFrameId", pR.AllPlayerInputsBuffer.StFrameId), zap.Any("EdFrameId", pR.AllPlayerInputsBuffer.EdFrameId))
|
||||||
}
|
}
|
||||||
@ -987,7 +977,7 @@ func (pR *Room) StopBattleForSettlement() {
|
|||||||
for playerId, _ := range pR.Players {
|
for playerId, _ := range pR.Players {
|
||||||
assembledFrame := pb.RoomDownsyncFrame{
|
assembledFrame := pb.RoomDownsyncFrame{
|
||||||
Id: pR.Tick,
|
Id: pR.Tick,
|
||||||
RefFrameId: 0, // Hardcoded for now.
|
RefFrameId: pR.Tick, // Hardcoded for now.
|
||||||
Players: toPbPlayers(pR.Players),
|
Players: toPbPlayers(pR.Players),
|
||||||
SentAt: utils.UnixtimeMilli(),
|
SentAt: utils.UnixtimeMilli(),
|
||||||
CountdownNanos: -1, // TODO: Replace this magic constant!
|
CountdownNanos: -1, // TODO: Replace this magic constant!
|
||||||
@ -1027,12 +1017,12 @@ func (pR *Room) onBattlePrepare(cb BattleStartCbType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
battleReadyToStartFrame := pb.RoomDownsyncFrame{
|
battleReadyToStartFrame := pb.RoomDownsyncFrame{
|
||||||
Id: pR.Tick,
|
Id: pR.Tick,
|
||||||
Players: toPbPlayers(pR.Players),
|
Players: toPbPlayers(pR.Players),
|
||||||
SentAt: utils.UnixtimeMilli(),
|
SentAt: utils.UnixtimeMilli(),
|
||||||
RefFrameId: MAGIC_ROOM_DOWNSYNC_FRAME_ID_BATTLE_READY_TO_START,
|
RefFrameId: MAGIC_ROOM_DOWNSYNC_FRAME_ID_BATTLE_READY_TO_START,
|
||||||
PlayerMetas: playerMetas,
|
PlayerMetas: playerMetas,
|
||||||
CountdownNanos: pR.BattleDurationNanos,
|
CountdownNanos: pR.BattleDurationNanos,
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info("Sending out frame for RoomBattleState.PREPARE ", zap.Any("battleReadyToStartFrame", battleReadyToStartFrame))
|
Logger.Info("Sending out frame for RoomBattleState.PREPARE ", zap.Any("battleReadyToStartFrame", battleReadyToStartFrame))
|
||||||
|
@ -109,23 +109,23 @@ func InitRoomHeapManager() {
|
|||||||
Tick: 0,
|
Tick: 0,
|
||||||
EffectivePlayerCount: 0,
|
EffectivePlayerCount: 0,
|
||||||
//BattleDurationNanos: int64(5 * 1000 * 1000 * 1000),
|
//BattleDurationNanos: int64(5 * 1000 * 1000 * 1000),
|
||||||
BattleDurationNanos: int64(30 * 1000 * 1000 * 1000),
|
BattleDurationNanos: int64(30 * 1000 * 1000 * 1000),
|
||||||
ServerFPS: 60,
|
ServerFPS: 60,
|
||||||
Treasures: make(map[int32]*Treasure),
|
Treasures: make(map[int32]*Treasure),
|
||||||
Traps: make(map[int32]*Trap),
|
Traps: make(map[int32]*Trap),
|
||||||
GuardTowers: make(map[int32]*GuardTower),
|
GuardTowers: make(map[int32]*GuardTower),
|
||||||
Bullets: make(map[int32]*Bullet),
|
Bullets: make(map[int32]*Bullet),
|
||||||
SpeedShoes: make(map[int32]*SpeedShoe),
|
SpeedShoes: make(map[int32]*SpeedShoe),
|
||||||
Barriers: make(map[int32]*Barrier),
|
Barriers: make(map[int32]*Barrier),
|
||||||
Pumpkins: make(map[int32]*Pumpkin),
|
Pumpkins: make(map[int32]*Pumpkin),
|
||||||
AccumulatedLocalIdForBullets: 0,
|
AccumulatedLocalIdForBullets: 0,
|
||||||
AllPlayerInputsBuffer: NewRingBuffer(1024),
|
AllPlayerInputsBuffer: NewRingBuffer(1024),
|
||||||
LastAllConfirmedInputFrameId: -1,
|
LastAllConfirmedInputFrameId: -1,
|
||||||
LastAllConfirmedInputFrameIdWithChange: -1,
|
LastAllConfirmedInputFrameIdWithChange: -1,
|
||||||
LastAllConfirmedInputList: make([]uint64, roomCapacity),
|
LastAllConfirmedInputList: make([]uint64, roomCapacity),
|
||||||
InputDelayFrames: 4,
|
InputDelayFrames: 4,
|
||||||
InputScaleFrames: 2,
|
InputScaleFrames: 2,
|
||||||
JoinIndexBooleanArr: joinIndexBooleanArr,
|
JoinIndexBooleanArr: joinIndexBooleanArr,
|
||||||
}
|
}
|
||||||
roomMap[pq[i].Id] = pq[i]
|
roomMap[pq[i].Id] = pq[i]
|
||||||
pq[i].ChooseStage()
|
pq[i].ChooseStage()
|
||||||
|
@ -1140,9 +1140,8 @@ type RoomDownsyncFrame struct {
|
|||||||
Traps map[int32]*Trap `protobuf:"bytes,7,rep,name=traps,proto3" json:"traps,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
Traps map[int32]*Trap `protobuf:"bytes,7,rep,name=traps,proto3" json:"traps,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
Bullets map[int32]*Bullet `protobuf:"bytes,8,rep,name=bullets,proto3" json:"bullets,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
Bullets map[int32]*Bullet `protobuf:"bytes,8,rep,name=bullets,proto3" json:"bullets,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
SpeedShoes map[int32]*SpeedShoe `protobuf:"bytes,9,rep,name=speedShoes,proto3" json:"speedShoes,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
SpeedShoes map[int32]*SpeedShoe `protobuf:"bytes,9,rep,name=speedShoes,proto3" json:"speedShoes,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
Pumpkin map[int32]*Pumpkin `protobuf:"bytes,10,rep,name=pumpkin,proto3" json:"pumpkin,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
GuardTowers map[int32]*GuardTower `protobuf:"bytes,10,rep,name=guardTowers,proto3" json:"guardTowers,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
GuardTowers map[int32]*GuardTower `protobuf:"bytes,11,rep,name=guardTowers,proto3" json:"guardTowers,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
PlayerMetas map[int32]*PlayerMeta `protobuf:"bytes,11,rep,name=playerMetas,proto3" json:"playerMetas,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
PlayerMetas map[int32]*PlayerMeta `protobuf:"bytes,12,rep,name=playerMetas,proto3" json:"playerMetas,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RoomDownsyncFrame) Reset() {
|
func (x *RoomDownsyncFrame) Reset() {
|
||||||
@ -1240,13 +1239,6 @@ func (x *RoomDownsyncFrame) GetSpeedShoes() map[int32]*SpeedShoe {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RoomDownsyncFrame) GetPumpkin() map[int32]*Pumpkin {
|
|
||||||
if x != nil {
|
|
||||||
return x.Pumpkin
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RoomDownsyncFrame) GetGuardTowers() map[int32]*GuardTower {
|
func (x *RoomDownsyncFrame) GetGuardTowers() map[int32]*GuardTower {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.GuardTowers
|
return x.GuardTowers
|
||||||
@ -1778,8 +1770,8 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
|
|||||||
0x28, 0x05, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x04, 0x20,
|
0x28, 0x05, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x04, 0x20,
|
||||||
0x01, 0x28, 0x01, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28,
|
0x01, 0x28, 0x01, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||||
0x01, 0x52, 0x01, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18,
|
0x01, 0x52, 0x01, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18,
|
||||||
0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0xbb,
|
0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0x9a,
|
||||||
0x0b, 0x0a, 0x11, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46,
|
0x0a, 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,
|
0x72, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
|
||||||
0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||||
0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x46, 0x72, 0x61,
|
0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x46, 0x72, 0x61,
|
||||||
@ -1811,123 +1803,113 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
|
|||||||
0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73,
|
0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73,
|
||||||
0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x53, 0x68,
|
0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x53, 0x68,
|
||||||
0x6f, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x65, 0x64, 0x53,
|
0x6f, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x65, 0x64, 0x53,
|
||||||
0x68, 0x6f, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x07, 0x70, 0x75, 0x6d, 0x70, 0x6b, 0x69, 0x6e, 0x18,
|
0x68, 0x6f, 0x65, 0x73, 0x12, 0x55, 0x0a, 0x0b, 0x67, 0x75, 0x61, 0x72, 0x64, 0x54, 0x6f, 0x77,
|
||||||
0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x72, 0x65, 0x61,
|
||||||
0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e,
|
0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d,
|
||||||
0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x75, 0x6d, 0x70, 0x6b, 0x69,
|
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x47, 0x75,
|
||||||
0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x75, 0x6d, 0x70, 0x6b, 0x69, 0x6e, 0x12,
|
0x61, 0x72, 0x64, 0x54, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b,
|
||||||
0x55, 0x0a, 0x0b, 0x67, 0x75, 0x61, 0x72, 0x64, 0x54, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x18, 0x0b,
|
0x67, 0x75, 0x61, 0x72, 0x64, 0x54, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x12, 0x55, 0x0a, 0x0b, 0x70,
|
||||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68,
|
0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b,
|
||||||
0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73,
|
0x32, 0x33, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65,
|
||||||
0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x47, 0x75, 0x61, 0x72, 0x64, 0x54, 0x6f,
|
0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46,
|
||||||
0x77, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x67, 0x75, 0x61, 0x72, 0x64,
|
0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73,
|
||||||
0x54, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x12, 0x55, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72,
|
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74,
|
||||||
0x4d, 0x65, 0x74, 0x61, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x72,
|
0x61, 0x73, 0x1a, 0x53, 0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74,
|
||||||
0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f,
|
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||||
0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e,
|
0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
|
||||||
0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75,
|
||||||
0x52, 0x0b, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x1a, 0x53, 0x0a,
|
0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61,
|
||||||
0x0c, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
|
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, 0x0e, 0x54, 0x72, 0x65, 0x61, 0x73,
|
||||||
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
|
0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||||
0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76,
|
||||||
0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78,
|
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x65,
|
||||||
0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x54, 0x72, 0x65,
|
||||||
0x38, 0x01, 0x1a, 0x57, 0x0a, 0x0e, 0x54, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x45,
|
0x61, 0x73, 0x75, 0x72, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
|
||||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x1a, 0x4f, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||||
0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||||
0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x54, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
0x15, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72,
|
||||||
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4f, 0x0a, 0x0a, 0x54,
|
0x78, 0x2e, 0x54, 0x72, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||||
0x72, 0x61, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
0x01, 0x1a, 0x53, 0x0a, 0x0c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76,
|
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03,
|
||||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x72, 0x65,
|
0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||||
0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x54, 0x72, 0x61,
|
0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e,
|
||||||
0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x53, 0x0a, 0x0c,
|
0x74, 0x65, 0x72, 0x78, 0x2e, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c,
|
||||||
0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, 0x0f, 0x53, 0x70, 0x65, 0x65, 0x64, 0x53,
|
||||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d,
|
0x68, 0x6f, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76,
|
||||||
0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e,
|
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x65,
|
||||||
0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x53, 0x70, 0x65,
|
||||||
0x01, 0x1a, 0x59, 0x0a, 0x0f, 0x53, 0x70, 0x65, 0x65, 0x64, 0x53, 0x68, 0x6f, 0x65, 0x73, 0x45,
|
0x65, 0x64, 0x53, 0x68, 0x6f, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x01, 0x1a, 0x5b, 0x0a, 0x10, 0x47, 0x75, 0x61, 0x72, 0x64, 0x54, 0x6f, 0x77, 0x65, 0x72, 0x73,
|
||||||
0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||||
0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x53, 0x68, 0x6f,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72,
|
||||||
0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x54, 0x0a, 0x0c,
|
0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x47, 0x75, 0x61, 0x72, 0x64, 0x54, 0x6f,
|
||||||
0x50, 0x75, 0x6d, 0x70, 0x6b, 0x69, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
0x77, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5b,
|
||||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e,
|
0x0a, 0x10, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x45, 0x6e, 0x74,
|
||||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e,
|
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||||
0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e,
|
0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
|
||||||
0x50, 0x75, 0x6d, 0x70, 0x6b, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75,
|
||||||
0x38, 0x01, 0x1a, 0x5b, 0x0a, 0x10, 0x47, 0x75, 0x61, 0x72, 0x64, 0x54, 0x6f, 0x77, 0x65, 0x72,
|
0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61,
|
||||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x10, 0x49,
|
||||||
0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12,
|
||||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75,
|
0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18,
|
||||||
0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x47, 0x75, 0x61, 0x72, 0x64, 0x54,
|
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
|
||||||
0x6f, 0x77, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
|
0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x44, 0x69,
|
||||||
0x5b, 0x0a, 0x10, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x45, 0x6e,
|
0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64,
|
||||||
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
|
0x44, 0x69, 0x72, 0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
|
||||||
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
|
0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70,
|
||||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68,
|
0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||||
0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74,
|
0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a,
|
||||||
0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x10,
|
0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04,
|
||||||
0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63,
|
0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63,
|
||||||
0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
|
0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
|
0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73,
|
||||||
0x6d, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x44,
|
0x74, 0x22, 0x3b, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70,
|
||||||
0x69, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65,
|
0x73, 0x79, 0x6e, 0x63, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69,
|
||||||
0x64, 0x44, 0x69, 0x72, 0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
|
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63,
|
||||||
0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e,
|
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xca,
|
||||||
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
|
0x02, 0x0a, 0x05, 0x57, 0x73, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49,
|
||||||
0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c,
|
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a,
|
||||||
0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28,
|
0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
|
||||||
0x04, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d,
|
0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63,
|
||||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20,
|
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09,
|
||||||
0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69,
|
0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||||
0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55,
|
0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63,
|
||||||
0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54,
|
0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f,
|
0x05, 0x52, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
|
||||||
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
|
0x12, 0x2e, 0x0a, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46,
|
||||||
0xca, 0x02, 0x0a, 0x05, 0x57, 0x73, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67,
|
0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63,
|
||||||
0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12,
|
0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
|
||||||
0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
0x12, 0x57, 0x0a, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70,
|
||||||
0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61,
|
0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||||
0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a,
|
0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72,
|
||||||
0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
|
0x78, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79,
|
||||||
0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61,
|
0x6e, 0x63, 0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70,
|
||||||
0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01,
|
0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x30, 0x0a, 0x02, 0x68, 0x62, 0x18,
|
||||||
0x28, 0x05, 0x52, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
|
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
|
||||||
0x64, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74,
|
0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61,
|
||||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61,
|
0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x02, 0x68, 0x62, 0x22, 0xa4, 0x02, 0x0a, 0x06,
|
||||||
0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
|
0x57, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20,
|
||||||
0x64, 0x12, 0x57, 0x0a, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55,
|
0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68, 0x6f,
|
||||||
0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b,
|
0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x65,
|
||||||
0x32, 0x21, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65,
|
0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63,
|
||||||
0x72, 0x78, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73,
|
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x34, 0x0a, 0x03,
|
||||||
0x79, 0x6e, 0x63, 0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55,
|
0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x65, 0x61,
|
||||||
0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x30, 0x0a, 0x02, 0x68, 0x62,
|
0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d,
|
||||||
0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72,
|
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72,
|
||||||
0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65,
|
0x64, 0x66, 0x12, 0x5d, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||||
0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x02, 0x68, 0x62, 0x22, 0xa4, 0x02, 0x0a,
|
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20,
|
||||||
0x06, 0x57, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01,
|
0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75,
|
||||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68,
|
0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||||
0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b,
|
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46,
|
||||||
0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61,
|
0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63,
|
||||||
0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x34, 0x0a,
|
0x68, 0x12, 0x3f, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20,
|
||||||
0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x65,
|
0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75,
|
||||||
0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f,
|
0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
|
||||||
0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03,
|
0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61,
|
||||||
0x72, 0x64, 0x66, 0x12, 0x5d, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
|
0x6d, 0x65, 0x42, 0x03, 0x5a, 0x01, 0x2e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05,
|
|
||||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68,
|
|
||||||
0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 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, 0x3f, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x06,
|
|
||||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68,
|
|
||||||
0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 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, 0x42, 0x03, 0x5a, 0x01, 0x2e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -1942,7 +1924,7 @@ func file_room_downsync_frame_proto_rawDescGZIP() []byte {
|
|||||||
return file_room_downsync_frame_proto_rawDescData
|
return file_room_downsync_frame_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 30)
|
var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 29)
|
||||||
var file_room_downsync_frame_proto_goTypes = []interface{}{
|
var file_room_downsync_frame_proto_goTypes = []interface{}{
|
||||||
(*Direction)(nil), // 0: treasurehunterx.Direction
|
(*Direction)(nil), // 0: treasurehunterx.Direction
|
||||||
(*Vec2D)(nil), // 1: treasurehunterx.Vec2D
|
(*Vec2D)(nil), // 1: treasurehunterx.Vec2D
|
||||||
@ -1971,9 +1953,8 @@ var file_room_downsync_frame_proto_goTypes = []interface{}{
|
|||||||
nil, // 24: treasurehunterx.RoomDownsyncFrame.TrapsEntry
|
nil, // 24: treasurehunterx.RoomDownsyncFrame.TrapsEntry
|
||||||
nil, // 25: treasurehunterx.RoomDownsyncFrame.BulletsEntry
|
nil, // 25: treasurehunterx.RoomDownsyncFrame.BulletsEntry
|
||||||
nil, // 26: treasurehunterx.RoomDownsyncFrame.SpeedShoesEntry
|
nil, // 26: treasurehunterx.RoomDownsyncFrame.SpeedShoesEntry
|
||||||
nil, // 27: treasurehunterx.RoomDownsyncFrame.PumpkinEntry
|
nil, // 27: treasurehunterx.RoomDownsyncFrame.GuardTowersEntry
|
||||||
nil, // 28: treasurehunterx.RoomDownsyncFrame.GuardTowersEntry
|
nil, // 28: treasurehunterx.RoomDownsyncFrame.PlayerMetasEntry
|
||||||
nil, // 29: treasurehunterx.RoomDownsyncFrame.PlayerMetasEntry
|
|
||||||
}
|
}
|
||||||
var file_room_downsync_frame_proto_depIdxs = []int32{
|
var file_room_downsync_frame_proto_depIdxs = []int32{
|
||||||
1, // 0: treasurehunterx.Polygon2D.Anchor:type_name -> treasurehunterx.Vec2D
|
1, // 0: treasurehunterx.Polygon2D.Anchor:type_name -> treasurehunterx.Vec2D
|
||||||
@ -1990,29 +1971,27 @@ var file_room_downsync_frame_proto_depIdxs = []int32{
|
|||||||
24, // 11: treasurehunterx.RoomDownsyncFrame.traps:type_name -> treasurehunterx.RoomDownsyncFrame.TrapsEntry
|
24, // 11: treasurehunterx.RoomDownsyncFrame.traps:type_name -> treasurehunterx.RoomDownsyncFrame.TrapsEntry
|
||||||
25, // 12: treasurehunterx.RoomDownsyncFrame.bullets:type_name -> treasurehunterx.RoomDownsyncFrame.BulletsEntry
|
25, // 12: treasurehunterx.RoomDownsyncFrame.bullets:type_name -> treasurehunterx.RoomDownsyncFrame.BulletsEntry
|
||||||
26, // 13: treasurehunterx.RoomDownsyncFrame.speedShoes:type_name -> treasurehunterx.RoomDownsyncFrame.SpeedShoesEntry
|
26, // 13: treasurehunterx.RoomDownsyncFrame.speedShoes:type_name -> treasurehunterx.RoomDownsyncFrame.SpeedShoesEntry
|
||||||
27, // 14: treasurehunterx.RoomDownsyncFrame.pumpkin:type_name -> treasurehunterx.RoomDownsyncFrame.PumpkinEntry
|
27, // 14: treasurehunterx.RoomDownsyncFrame.guardTowers:type_name -> treasurehunterx.RoomDownsyncFrame.GuardTowersEntry
|
||||||
28, // 15: treasurehunterx.RoomDownsyncFrame.guardTowers:type_name -> treasurehunterx.RoomDownsyncFrame.GuardTowersEntry
|
28, // 15: treasurehunterx.RoomDownsyncFrame.playerMetas:type_name -> treasurehunterx.RoomDownsyncFrame.PlayerMetasEntry
|
||||||
29, // 16: treasurehunterx.RoomDownsyncFrame.playerMetas:type_name -> treasurehunterx.RoomDownsyncFrame.PlayerMetasEntry
|
15, // 16: treasurehunterx.WsReq.inputFrameUpsyncBatch:type_name -> treasurehunterx.InputFrameUpsync
|
||||||
15, // 17: treasurehunterx.WsReq.inputFrameUpsyncBatch:type_name -> treasurehunterx.InputFrameUpsync
|
17, // 17: treasurehunterx.WsReq.hb:type_name -> treasurehunterx.HeartbeatUpsync
|
||||||
17, // 18: treasurehunterx.WsReq.hb:type_name -> treasurehunterx.HeartbeatUpsync
|
14, // 18: treasurehunterx.WsResp.rdf:type_name -> treasurehunterx.RoomDownsyncFrame
|
||||||
14, // 19: treasurehunterx.WsResp.rdf:type_name -> treasurehunterx.RoomDownsyncFrame
|
16, // 19: treasurehunterx.WsResp.inputFrameDownsyncBatch:type_name -> treasurehunterx.InputFrameDownsync
|
||||||
16, // 20: treasurehunterx.WsResp.inputFrameDownsyncBatch:type_name -> treasurehunterx.InputFrameDownsync
|
5, // 20: treasurehunterx.WsResp.bciFrame:type_name -> treasurehunterx.BattleColliderInfo
|
||||||
5, // 21: treasurehunterx.WsResp.bciFrame:type_name -> treasurehunterx.BattleColliderInfo
|
3, // 21: treasurehunterx.BattleColliderInfo.StrToVec2DListMapEntry.value:type_name -> treasurehunterx.Vec2DList
|
||||||
3, // 22: treasurehunterx.BattleColliderInfo.StrToVec2DListMapEntry.value:type_name -> treasurehunterx.Vec2DList
|
4, // 22: treasurehunterx.BattleColliderInfo.StrToPolygon2DListMapEntry.value:type_name -> treasurehunterx.Polygon2DList
|
||||||
4, // 23: treasurehunterx.BattleColliderInfo.StrToPolygon2DListMapEntry.value:type_name -> treasurehunterx.Polygon2DList
|
6, // 23: treasurehunterx.RoomDownsyncFrame.PlayersEntry.value:type_name -> treasurehunterx.Player
|
||||||
6, // 24: treasurehunterx.RoomDownsyncFrame.PlayersEntry.value:type_name -> treasurehunterx.Player
|
8, // 24: treasurehunterx.RoomDownsyncFrame.TreasuresEntry.value:type_name -> treasurehunterx.Treasure
|
||||||
8, // 25: treasurehunterx.RoomDownsyncFrame.TreasuresEntry.value:type_name -> treasurehunterx.Treasure
|
10, // 25: treasurehunterx.RoomDownsyncFrame.TrapsEntry.value:type_name -> treasurehunterx.Trap
|
||||||
10, // 26: treasurehunterx.RoomDownsyncFrame.TrapsEntry.value:type_name -> treasurehunterx.Trap
|
9, // 26: treasurehunterx.RoomDownsyncFrame.BulletsEntry.value:type_name -> treasurehunterx.Bullet
|
||||||
9, // 27: treasurehunterx.RoomDownsyncFrame.BulletsEntry.value:type_name -> treasurehunterx.Bullet
|
11, // 27: treasurehunterx.RoomDownsyncFrame.SpeedShoesEntry.value:type_name -> treasurehunterx.SpeedShoe
|
||||||
11, // 28: treasurehunterx.RoomDownsyncFrame.SpeedShoesEntry.value:type_name -> treasurehunterx.SpeedShoe
|
13, // 28: treasurehunterx.RoomDownsyncFrame.GuardTowersEntry.value:type_name -> treasurehunterx.GuardTower
|
||||||
12, // 29: treasurehunterx.RoomDownsyncFrame.PumpkinEntry.value:type_name -> treasurehunterx.Pumpkin
|
7, // 29: treasurehunterx.RoomDownsyncFrame.PlayerMetasEntry.value:type_name -> treasurehunterx.PlayerMeta
|
||||||
13, // 30: treasurehunterx.RoomDownsyncFrame.GuardTowersEntry.value:type_name -> treasurehunterx.GuardTower
|
30, // [30:30] is the sub-list for method output_type
|
||||||
7, // 31: treasurehunterx.RoomDownsyncFrame.PlayerMetasEntry.value:type_name -> treasurehunterx.PlayerMeta
|
30, // [30:30] is the sub-list for method input_type
|
||||||
32, // [32:32] is the sub-list for method output_type
|
30, // [30:30] is the sub-list for extension type_name
|
||||||
32, // [32:32] is the sub-list for method input_type
|
30, // [30:30] is the sub-list for extension extendee
|
||||||
32, // [32:32] is the sub-list for extension type_name
|
0, // [0:30] is the sub-list for field type_name
|
||||||
32, // [32:32] is the sub-list for extension extendee
|
|
||||||
0, // [0:32] is the sub-list for field type_name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_room_downsync_frame_proto_init() }
|
func init() { file_room_downsync_frame_proto_init() }
|
||||||
@ -2268,7 +2247,7 @@ func file_room_downsync_frame_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_room_downsync_frame_proto_rawDesc,
|
RawDescriptor: file_room_downsync_frame_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 30,
|
NumMessages: 29,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
@ -126,9 +126,8 @@ message RoomDownsyncFrame {
|
|||||||
map<int32, Trap> traps = 7;
|
map<int32, Trap> traps = 7;
|
||||||
map<int32, Bullet> bullets = 8;
|
map<int32, Bullet> bullets = 8;
|
||||||
map<int32, SpeedShoe> speedShoes = 9;
|
map<int32, SpeedShoe> speedShoes = 9;
|
||||||
map<int32, Pumpkin> pumpkin = 10;
|
map<int32, GuardTower> guardTowers = 10;
|
||||||
map<int32, GuardTower> guardTowers = 11;
|
map<int32, PlayerMeta> playerMetas = 11;
|
||||||
map<int32, PlayerMeta> playerMetas = 12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message InputFrameUpsync {
|
message InputFrameUpsync {
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"optimizationPolicy": 0,
|
"optimizationPolicy": 0,
|
||||||
"asyncLoadAssets": false
|
"asyncLoadAssets": false,
|
||||||
|
"readonly": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
@ -27,7 +28,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 1,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
@ -63,17 +63,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"groupIndex": 2,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -89,7 +78,19 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 2,
|
||||||
|
"groupIndex": 2,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
@ -100,7 +101,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": false,
|
"_active": false,
|
||||||
"_level": 0,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 3
|
"__id__": 3
|
||||||
@ -127,17 +127,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 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": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -153,7 +142,19 @@
|
|||||||
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.Label",
|
"__type__": "cc.Label",
|
||||||
@ -163,6 +164,7 @@
|
|||||||
"__id__": 2
|
"__id__": 2
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
"_useOriginalSize": false,
|
"_useOriginalSize": false,
|
||||||
"_string": "(0, 0)",
|
"_string": "(0, 0)",
|
||||||
"_N$string": "(0, 0)",
|
"_N$string": "(0, 0)",
|
||||||
@ -200,7 +202,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": false,
|
"_active": false,
|
||||||
"_level": 2,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 6
|
"__id__": 6
|
||||||
@ -227,17 +228,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 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": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -253,7 +243,19 @@
|
|||||||
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.ParticleSystem",
|
"__type__": "cc.ParticleSystem",
|
||||||
@ -263,6 +265,9 @@
|
|||||||
"__id__": 5
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 1,
|
||||||
"_custom": true,
|
"_custom": true,
|
||||||
"_file": {
|
"_file": {
|
||||||
"__uuid__": "b2687ac4-099e-403c-a192-ff477686f4f5"
|
"__uuid__": "b2687ac4-099e-403c-a192-ff477686f4f5"
|
||||||
@ -271,8 +276,6 @@
|
|||||||
"__uuid__": "472df5d3-35e7-4184-9e6c-7f41bee65ee3"
|
"__uuid__": "472df5d3-35e7-4184-9e6c-7f41bee65ee3"
|
||||||
},
|
},
|
||||||
"_texture": null,
|
"_texture": null,
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 1,
|
|
||||||
"_stopped": false,
|
"_stopped": false,
|
||||||
"playOnLoad": true,
|
"playOnLoad": true,
|
||||||
"autoRemoveOnFinish": false,
|
"autoRemoveOnFinish": false,
|
||||||
@ -329,6 +332,7 @@
|
|||||||
"x": 7,
|
"x": 7,
|
||||||
"y": 7
|
"y": 7
|
||||||
},
|
},
|
||||||
|
"_positionType": 1,
|
||||||
"positionType": 1,
|
"positionType": 1,
|
||||||
"emitterMode": 0,
|
"emitterMode": 0,
|
||||||
"gravity": {
|
"gravity": {
|
||||||
@ -372,7 +376,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 2,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 9
|
"__id__": 9
|
||||||
@ -399,17 +402,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 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": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -425,7 +417,19 @@
|
|||||||
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",
|
"__type__": "cc.Sprite",
|
||||||
@ -435,6 +439,13 @@
|
|||||||
"__id__": 8
|
"__id__": 8
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": {
|
"_spriteFrame": {
|
||||||
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
|
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
|
||||||
},
|
},
|
||||||
@ -449,12 +460,9 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": {
|
"_atlas": {
|
||||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||||
},
|
},
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -476,6 +484,9 @@
|
|||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": null,
|
"_spriteFrame": null,
|
||||||
"_type": 0,
|
"_type": 0,
|
||||||
"_sizeMode": 0,
|
"_sizeMode": 0,
|
||||||
@ -488,10 +499,7 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": null,
|
"_atlas": null,
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -549,8 +557,8 @@
|
|||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"animComp": null,
|
"animComp": null,
|
||||||
"baseSpeed": 300,
|
"baseSpeed": 50,
|
||||||
"speed": 200,
|
"speed": 50,
|
||||||
"lastMovedAt": 0,
|
"lastMovedAt": 0,
|
||||||
"eps": 0.1,
|
"eps": 0.1,
|
||||||
"magicLeanLowerBound": 0.414,
|
"magicLeanLowerBound": 0.414,
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"optimizationPolicy": 0,
|
"optimizationPolicy": 0,
|
||||||
"asyncLoadAssets": false
|
"asyncLoadAssets": false,
|
||||||
|
"readonly": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
@ -27,7 +28,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 1,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
@ -63,17 +63,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"groupIndex": 2,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -89,7 +78,19 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 2,
|
||||||
|
"groupIndex": 2,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
@ -100,7 +101,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": false,
|
"_active": false,
|
||||||
"_level": 0,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 3
|
"__id__": 3
|
||||||
@ -127,17 +127,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 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": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -153,7 +142,19 @@
|
|||||||
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.Label",
|
"__type__": "cc.Label",
|
||||||
@ -163,6 +164,7 @@
|
|||||||
"__id__": 2
|
"__id__": 2
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
"_useOriginalSize": false,
|
"_useOriginalSize": false,
|
||||||
"_string": "(0, 0)",
|
"_string": "(0, 0)",
|
||||||
"_N$string": "(0, 0)",
|
"_N$string": "(0, 0)",
|
||||||
@ -200,7 +202,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": false,
|
"_active": false,
|
||||||
"_level": 2,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 6
|
"__id__": 6
|
||||||
@ -227,17 +228,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 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": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -253,7 +243,19 @@
|
|||||||
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.ParticleSystem",
|
"__type__": "cc.ParticleSystem",
|
||||||
@ -263,6 +265,9 @@
|
|||||||
"__id__": 5
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 1,
|
||||||
"_custom": true,
|
"_custom": true,
|
||||||
"_file": {
|
"_file": {
|
||||||
"__uuid__": "b2687ac4-099e-403c-a192-ff477686f4f5"
|
"__uuid__": "b2687ac4-099e-403c-a192-ff477686f4f5"
|
||||||
@ -271,8 +276,6 @@
|
|||||||
"__uuid__": "472df5d3-35e7-4184-9e6c-7f41bee65ee3"
|
"__uuid__": "472df5d3-35e7-4184-9e6c-7f41bee65ee3"
|
||||||
},
|
},
|
||||||
"_texture": null,
|
"_texture": null,
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 1,
|
|
||||||
"_stopped": false,
|
"_stopped": false,
|
||||||
"playOnLoad": true,
|
"playOnLoad": true,
|
||||||
"autoRemoveOnFinish": false,
|
"autoRemoveOnFinish": false,
|
||||||
@ -329,6 +332,7 @@
|
|||||||
"x": 7,
|
"x": 7,
|
||||||
"y": 7
|
"y": 7
|
||||||
},
|
},
|
||||||
|
"_positionType": 1,
|
||||||
"positionType": 1,
|
"positionType": 1,
|
||||||
"emitterMode": 0,
|
"emitterMode": 0,
|
||||||
"gravity": {
|
"gravity": {
|
||||||
@ -372,7 +376,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 2,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 9
|
"__id__": 9
|
||||||
@ -399,17 +402,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 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": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@ -425,7 +417,19 @@
|
|||||||
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",
|
"__type__": "cc.Sprite",
|
||||||
@ -435,6 +439,13 @@
|
|||||||
"__id__": 8
|
"__id__": 8
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": {
|
"_spriteFrame": {
|
||||||
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
|
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
|
||||||
},
|
},
|
||||||
@ -449,12 +460,9 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": {
|
"_atlas": {
|
||||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||||
},
|
},
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -476,6 +484,9 @@
|
|||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": null,
|
"_spriteFrame": null,
|
||||||
"_type": 0,
|
"_type": 0,
|
||||||
"_sizeMode": 0,
|
"_sizeMode": 0,
|
||||||
@ -488,10 +499,7 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": null,
|
"_atlas": null,
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -549,8 +557,8 @@
|
|||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"animComp": null,
|
"animComp": null,
|
||||||
"baseSpeed": 300,
|
"baseSpeed": 50,
|
||||||
"speed": 200,
|
"speed": 50,
|
||||||
"lastMovedAt": 0,
|
"lastMovedAt": 0,
|
||||||
"eps": 0.1,
|
"eps": 0.1,
|
||||||
"magicLeanLowerBound": 0.414,
|
"magicLeanLowerBound": 0.414,
|
||||||
|
@ -440,7 +440,7 @@
|
|||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
209.7912853806815,
|
216.05530045313827,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -2991,9 +2991,6 @@
|
|||||||
"loadingPrefab": {
|
"loadingPrefab": {
|
||||||
"__uuid__": "f2a3cece-30bf-4f62-bc20-34d44a9ddf98"
|
"__uuid__": "f2a3cece-30bf-4f62-bc20-34d44a9ddf98"
|
||||||
},
|
},
|
||||||
"wechatLoginTips": {
|
|
||||||
"__id__": 68
|
|
||||||
},
|
|
||||||
"_id": "51YNpecnJBea8vzAxGdkv2"
|
"_id": "51YNpecnJBea8vzAxGdkv2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "1.2.5",
|
|
||||||
"uuid": "475b849b-44b3-4390-982d-bd0d9e695093",
|
|
||||||
"asyncLoadAssets": false,
|
|
||||||
"autoReleaseAssets": false,
|
|
||||||
"subMetas": {}
|
|
||||||
}
|
|
@ -8,11 +8,11 @@ module.export = cc.Class({
|
|||||||
},
|
},
|
||||||
baseSpeed: {
|
baseSpeed: {
|
||||||
type: cc.Float,
|
type: cc.Float,
|
||||||
default: 300,
|
default: 50,
|
||||||
},
|
},
|
||||||
speed: {
|
speed: {
|
||||||
type: cc.Float,
|
type: cc.Float,
|
||||||
default: 300
|
default: 50
|
||||||
},
|
},
|
||||||
lastMovedAt: {
|
lastMovedAt: {
|
||||||
type: cc.Float,
|
type: cc.Float,
|
||||||
@ -35,12 +35,6 @@ module.export = cc.Class({
|
|||||||
// LIFE-CYCLE CALLBACKS:
|
// LIFE-CYCLE CALLBACKS:
|
||||||
start() {
|
start() {
|
||||||
const self = this;
|
const self = this;
|
||||||
self.contactedControlledPlayers = [];
|
|
||||||
self.contactedNPCPlayers = [];
|
|
||||||
self.coveringShelterZReducers = [];
|
|
||||||
|
|
||||||
self.computedNewDifferentPosLocalToParentWithinCurrentFrame = null;
|
|
||||||
self.actionMangerSingleton = new cc.ActionManager();
|
|
||||||
self.activeDirection = {
|
self.activeDirection = {
|
||||||
dx: 0,
|
dx: 0,
|
||||||
dy: 0
|
dy: 0
|
||||||
@ -61,7 +55,6 @@ module.export = cc.Class({
|
|||||||
};
|
};
|
||||||
const canvasNode = self.mapNode.parent;
|
const canvasNode = self.mapNode.parent;
|
||||||
self.mapIns = self.mapNode.getComponent("Map");
|
self.mapIns = self.mapNode.getComponent("Map");
|
||||||
self.contactedBarriers = [];
|
|
||||||
const joystickInputControllerScriptIns = canvasNode.getComponent("TouchEventsManager");
|
const joystickInputControllerScriptIns = canvasNode.getComponent("TouchEventsManager");
|
||||||
self.ctrl = joystickInputControllerScriptIns;
|
self.ctrl = joystickInputControllerScriptIns;
|
||||||
self.animComp = self.node.getComponent(cc.Animation);
|
self.animComp = self.node.getComponent(cc.Animation);
|
||||||
@ -93,330 +86,10 @@ module.export = cc.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_addCoveringShelterZReducer(comp) {
|
|
||||||
const self = this;
|
|
||||||
for (let coveringShelterZReducer of self.coveringShelterZReducers) {
|
|
||||||
if (coveringShelterZReducer._id == comp._id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.coveringShelterZReducers.push(comp);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeCoveringShelterZReducer(comp) {
|
|
||||||
const self = this;
|
|
||||||
self.coveringShelterZReducers = self.coveringShelterZReducers.filter((coveringShelterZReducer) => {
|
|
||||||
return coveringShelterZReducer._id != comp._id;
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_addContactedBarrier(collider) {
|
|
||||||
const self = this;
|
|
||||||
if (!self.contactedBarriers) {
|
|
||||||
cc.log("self.contactedBarriers is null or undefined" + self.contactedBarriers)
|
|
||||||
}
|
|
||||||
for (let contactedBarrier of self.contactedBarriers) {
|
|
||||||
if (contactedBarrier._id == collider._id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.contactedBarriers.push(collider);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeContactedBarrier(collider) {
|
|
||||||
const self = this;
|
|
||||||
self.contactedBarriers = self.contactedBarriers.filter((contactedBarrier) => {
|
|
||||||
return contactedBarrier._id != collider._id;
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_addContactedControlledPlayers(comp) {
|
|
||||||
const self = this;
|
|
||||||
for (let aComp of self.contactedControlledPlayers) {
|
|
||||||
if (aComp.uuid == comp.uuid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.contactedControlledPlayers.push(comp);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeContactedControlledPlayer(comp) {
|
|
||||||
const self = this;
|
|
||||||
self.contactedControlledPlayers = self.contactedControlledPlayers.filter((aComp) => {
|
|
||||||
return aComp.uuid != comp.uuid;
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_addContactedNPCPlayers(comp) {
|
|
||||||
const self = this;
|
|
||||||
for (let aComp of self.contactedNPCPlayers) {
|
|
||||||
if (aComp.uuid == comp.uuid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.contactedNPCPlayers.push(comp);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeContactedNPCPlayer(comp) {
|
|
||||||
const self = this;
|
|
||||||
self.contactedNPCPlayers = self.contactedNPCPlayers.filter((aComp) => {
|
|
||||||
return aComp.uuid != comp.uuid;
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_canMoveBy(vecToMoveBy) {
|
|
||||||
const self = this;
|
|
||||||
const computedNewDifferentPosLocalToParentWithinCurrentFrame = self.node.position.add(vecToMoveBy);
|
|
||||||
self.computedNewDifferentPosLocalToParentWithinCurrentFrame = computedNewDifferentPosLocalToParentWithinCurrentFrame;
|
|
||||||
|
|
||||||
if (tileCollisionManager.isOutOfMapNode(self.mapNode, computedNewDifferentPosLocalToParentWithinCurrentFrame)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentSelfColliderCircle = self.node.getComponent(cc.CircleCollider);
|
|
||||||
let nextSelfColliderCircle = null;
|
|
||||||
if (0 < self.contactedBarriers.length) {
|
|
||||||
/* To avoid unexpected buckling. */
|
|
||||||
const mutatedVecToMoveBy = vecToMoveBy.mul(5); // To help it escape the engaged `contactedBarriers`.
|
|
||||||
nextSelfColliderCircle = {
|
|
||||||
position: self.node.position.add(mutatedVecToMoveBy).add(currentSelfColliderCircle.offset),
|
|
||||||
radius: currentSelfColliderCircle.radius,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
nextSelfColliderCircle = {
|
|
||||||
position: computedNewDifferentPosLocalToParentWithinCurrentFrame.add(currentSelfColliderCircle.offset),
|
|
||||||
radius: currentSelfColliderCircle.radius,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let contactedBarrier of self.contactedBarriers) {
|
|
||||||
let contactedBarrierPolygonLocalToParentWithinCurrentFrame = [];
|
|
||||||
for (let p of contactedBarrier.points) {
|
|
||||||
contactedBarrierPolygonLocalToParentWithinCurrentFrame.push(contactedBarrier.node.position.add(p));
|
|
||||||
}
|
|
||||||
if (cc.Intersection.pointInPolygon(nextSelfColliderCircle.position, contactedBarrierPolygonLocalToParentWithinCurrentFrame)) {
|
|
||||||
// Make sure that the player is "leaving" the PolygonCollider.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (cc.Intersection.polygonCircle(contactedBarrierPolygonLocalToParentWithinCurrentFrame, nextSelfColliderCircle)) {
|
|
||||||
if (null == self.firstContactedEdge) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (null != self.firstContactedEdge && self.firstContactedEdge.associatedBarrier != contactedBarrier) {
|
|
||||||
const res = self._calculateTangentialMovementAttrs(nextSelfColliderCircle, contactedBarrier);
|
|
||||||
if (null == res.contactedEdge) {
|
|
||||||
// Otherwise, the current movement is going to transit smoothly onto the next PolygonCollider.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In a subclass, use
|
|
||||||
*
|
|
||||||
* _canMoveBy(vecToMoveBy) {
|
|
||||||
* BasePlayer.prototype._canMoveBy.call(this, vecToMoveBy);
|
|
||||||
* // Customized codes.
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Reference http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/class.html#override
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
|
|
||||||
_calculateTangentialMovementAttrs(currentSelfColliderCircle, contactedBarrier) {
|
|
||||||
/*
|
|
||||||
* Theoretically when the `contactedBarrier` is a convex polygon and the `PlayerCollider` is a circle, there can be only 1 `contactedEdge` for each `contactedBarrier`. Except only for around the corner.
|
|
||||||
*
|
|
||||||
* We should avoid the possibility of players hitting the "corners of convex polygons" by map design wherever & whenever possible.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const self = this;
|
|
||||||
const sDir = self.activeDirection;
|
|
||||||
const currentSelfColliderCircleCentrePos = (currentSelfColliderCircle.position ? currentSelfColliderCircle.position : self.node.position.add(currentSelfColliderCircle.offset));
|
|
||||||
const currentSelfColliderCircleRadius = currentSelfColliderCircle.radius;
|
|
||||||
let contactedEdgeCandidateList = [];
|
|
||||||
let skinDepthThreshold = 0.45*currentSelfColliderCircleRadius;
|
|
||||||
for (let i = 0; i < contactedBarrier.points.length; ++i) {
|
|
||||||
const stPoint = contactedBarrier.points[i].add(contactedBarrier.offset).add(contactedBarrier.node.position);
|
|
||||||
const edPoint = (i == contactedBarrier.points.length - 1 ? contactedBarrier.points[0].add(contactedBarrier.offset).add(contactedBarrier.node.position) : contactedBarrier.points[1 + i].add(contactedBarrier.offset).add(contactedBarrier.node.position));
|
|
||||||
const tmpVSt = stPoint.sub(currentSelfColliderCircleCentrePos);
|
|
||||||
const tmpVEd = edPoint.sub(currentSelfColliderCircleCentrePos);
|
|
||||||
const crossProdScalar = tmpVSt.cross(tmpVEd);
|
|
||||||
if (0 < crossProdScalar) {
|
|
||||||
// If moving parallel along `st <-> ed`, the trajectory of `currentSelfColliderCircleCentrePos` will cut inside the polygon.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const dis = cc.Intersection.pointLineDistance(currentSelfColliderCircleCentrePos, stPoint, edPoint, true);
|
|
||||||
if (dis > currentSelfColliderCircleRadius) continue;
|
|
||||||
if (dis < skinDepthThreshold) continue;
|
|
||||||
contactedEdgeCandidateList.push({
|
|
||||||
st: stPoint,
|
|
||||||
ed: edPoint,
|
|
||||||
associatedBarrier: contactedBarrier,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let contactedEdge = null;
|
|
||||||
let contactedEdgeDir = null;
|
|
||||||
let largestInnerProdAbs = Number.MIN_VALUE;
|
|
||||||
|
|
||||||
if (0 < contactedEdgeCandidateList.length) {
|
|
||||||
const sDirMag = Math.sqrt(sDir.dx * sDir.dx + sDir.dy * sDir.dy);
|
|
||||||
for (let contactedEdgeCandidate of contactedEdgeCandidateList) {
|
|
||||||
const tmp = contactedEdgeCandidate.ed.sub(contactedEdgeCandidate.st);
|
|
||||||
const contactedEdgeDirCandidate = {
|
|
||||||
dx: tmp.x,
|
|
||||||
dy: tmp.y,
|
|
||||||
};
|
|
||||||
const contactedEdgeDirCandidateMag = Math.sqrt(contactedEdgeDirCandidate.dx * contactedEdgeDirCandidate.dx + contactedEdgeDirCandidate.dy * contactedEdgeDirCandidate.dy);
|
|
||||||
const innerDotProd = (sDir.dx * contactedEdgeDirCandidate.dx + sDir.dy * contactedEdgeDirCandidate.dy)/(sDirMag * contactedEdgeDirCandidateMag);
|
|
||||||
const innerDotProdThresholdMag = 0.7;
|
|
||||||
if ((0 > innerDotProd && innerDotProd > -innerDotProdThresholdMag) || (0 < innerDotProd && innerDotProd < innerDotProdThresholdMag)) {
|
|
||||||
// Intentionally left blank, in this case the player is trying to escape from the `contactedEdge`.
|
|
||||||
continue;
|
|
||||||
} else if (innerDotProd > 0) {
|
|
||||||
const abs = Math.abs(innerDotProd);
|
|
||||||
if (abs > largestInnerProdAbs) {
|
|
||||||
contactedEdgeDir = contactedEdgeDirCandidate;
|
|
||||||
contactedEdge = contactedEdgeCandidate;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const abs = Math.abs(innerDotProd);
|
|
||||||
if (abs > largestInnerProdAbs) {
|
|
||||||
contactedEdgeDir = {
|
|
||||||
dx: -contactedEdgeDirCandidate.dx,
|
|
||||||
dy: -contactedEdgeDirCandidate.dy,
|
|
||||||
};
|
|
||||||
contactedEdge = contactedEdgeCandidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
contactedEdgeDir: contactedEdgeDir,
|
|
||||||
contactedEdge: contactedEdge,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
_calculateVecToMoveByWithChosenDir(elapsedTime, sDir) {
|
|
||||||
if (0 == sDir.dx && 0 == sDir.dy) {
|
|
||||||
return cc.v2();
|
|
||||||
}
|
|
||||||
const self = this;
|
|
||||||
const distanceToMove = (self.speed * elapsedTime);
|
|
||||||
const denominator = Math.sqrt(sDir.dx * sDir.dx + sDir.dy * sDir.dy);
|
|
||||||
const unitProjDx = (sDir.dx / denominator);
|
|
||||||
const unitProjDy = (sDir.dy / denominator);
|
|
||||||
return cc.v2(
|
|
||||||
distanceToMove * unitProjDx,
|
|
||||||
distanceToMove * unitProjDy,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_calculateVecToMoveBy(elapsedTime) {
|
|
||||||
const self = this;
|
|
||||||
// Note that `sDir` used in this method MUST BE a copy in RAM.
|
|
||||||
let sDir = {
|
|
||||||
dx: self.activeDirection.dx,
|
|
||||||
dy: self.activeDirection.dy,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (0 == sDir.dx && 0 == sDir.dy) {
|
|
||||||
return cc.v2();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.firstContactedEdge = null; // Reset everytime (temporary algorithm design, might change later).
|
|
||||||
if (0 < self.contactedBarriers.length) {
|
|
||||||
/*
|
|
||||||
* Hardcoded to take care of only the 1st `contactedEdge` of the 1st `contactedBarrier` for now. Each `contactedBarrier` must be "counterclockwisely convex polygonal", otherwise sliding doesn't work!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const contactedBarrier = self.contactedBarriers[0];
|
|
||||||
const currentSelfColliderCircle = self.node.getComponent(cc.CircleCollider);
|
|
||||||
const res = self._calculateTangentialMovementAttrs(currentSelfColliderCircle, contactedBarrier);
|
|
||||||
if (res.contactedEdge) {
|
|
||||||
self.firstContactedEdge = res.contactedEdge;
|
|
||||||
sDir = res.contactedEdgeDir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self._calculateVecToMoveByWithChosenDir(elapsedTime, sDir);
|
|
||||||
},
|
|
||||||
|
|
||||||
update(dt) {
|
update(dt) {
|
||||||
const self = this;
|
|
||||||
const vecToMoveBy = self._calculateVecToMoveBy(self.mapIns.rollbackEstimatedDt); // To be consistent w.r.t. rollback dynamics
|
|
||||||
// console.log("activeDirection=", self.activeDirection, "vecToMoveBy=", vecToMoveBy, ", computedNewDifferentPosLocalToParentWithinCurrentFrame=", self.computedNewDifferentPosLocalToParentWithinCurrentFrame);
|
|
||||||
if (self._canMoveBy(vecToMoveBy)) {
|
|
||||||
self.node.position = self.computedNewDifferentPosLocalToParentWithinCurrentFrame;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
lateUpdate(dt) {
|
lateUpdate(dt) {
|
||||||
const self = this;
|
|
||||||
const now = new Date().getTime();
|
|
||||||
self.lastMovedAt = now;
|
|
||||||
},
|
|
||||||
|
|
||||||
onCollisionEnter(other, self) {
|
|
||||||
const playerScriptIns = self.node.getComponent("SelfPlayer");
|
|
||||||
switch (other.node.name) {
|
|
||||||
case "NPCPlayer":
|
|
||||||
if ("NPCPlayer" != self.node.name) {
|
|
||||||
other.node.getComponent('NPCPlayer').showProfileTrigger();
|
|
||||||
}
|
|
||||||
playerScriptIns._addContactedNPCPlayers(other);
|
|
||||||
break;
|
|
||||||
case "PolygonBoundaryBarrier":
|
|
||||||
playerScriptIns._addContactedBarrier(other);
|
|
||||||
break;
|
|
||||||
case "PolygonBoundaryShelter":
|
|
||||||
break;
|
|
||||||
case "PolygonBoundaryShelterZReducer":
|
|
||||||
playerScriptIns._addCoveringShelterZReducer(other);
|
|
||||||
if (1 == playerScriptIns.coveringShelterZReducers.length) {
|
|
||||||
setLocalZOrder(self.node, 2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onCollisionStay(other, self) {
|
|
||||||
// TBD.
|
|
||||||
},
|
|
||||||
|
|
||||||
onCollisionExit(other, self) {
|
|
||||||
const playerScriptIns = self.getComponent("SelfPlayer");
|
|
||||||
switch (other.node.name) {
|
|
||||||
case "NPCPlayer":
|
|
||||||
other.node.getComponent('NPCPlayer').hideProfileTrigger();
|
|
||||||
playerScriptIns._removeContactedNPCPlayer(other);
|
|
||||||
break;
|
|
||||||
case "PolygonBoundaryBarrier":
|
|
||||||
playerScriptIns._removeContactedBarrier(other);
|
|
||||||
break;
|
|
||||||
case "PolygonBoundaryShelter":
|
|
||||||
break;
|
|
||||||
case "PolygonBoundaryShelterZReducer":
|
|
||||||
playerScriptIns._removeCoveringShelterZReducer(other);
|
|
||||||
if (0 == playerScriptIns.coveringShelterZReducers.length) {
|
|
||||||
setLocalZOrder(self.node, 5);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_generateRandomDirection() {
|
_generateRandomDirection() {
|
||||||
|
@ -22,7 +22,7 @@ cc.Class({
|
|||||||
if (!self.mapScriptIns) return;
|
if (!self.mapScriptIns) return;
|
||||||
if (!self.mapScriptIns.selfPlayerInfo) return;
|
if (!self.mapScriptIns.selfPlayerInfo) return;
|
||||||
if (!self.mapScriptIns.playerRichInfoDict) return;
|
if (!self.mapScriptIns.playerRichInfoDict) return;
|
||||||
const selfPlayerRichInfo = self.mapScriptIns.playerRichInfoDict[self.mapScriptIns.selfPlayerInfo.id];
|
const selfPlayerRichInfo = self.mapScriptIns.playerRichInfoDict.get(self.mapScriptIns.selfPlayerInfo.id);
|
||||||
if (!selfPlayerRichInfo) return;
|
if (!selfPlayerRichInfo) return;
|
||||||
const selfPlayerNode = selfPlayerRichInfo.node;
|
const selfPlayerNode = selfPlayerRichInfo.node;
|
||||||
if (!selfPlayerNode) return;
|
if (!selfPlayerNode) return;
|
||||||
|
@ -26,19 +26,6 @@ cc.Class({
|
|||||||
|
|
||||||
// LIFE-CYCLE CALLBACKS:
|
// LIFE-CYCLE CALLBACKS:
|
||||||
onLoad() {
|
onLoad() {
|
||||||
// WARNING: 不能保证在ws连接成功并且拿到boundRoomId后才运行到此处。
|
|
||||||
if (cc.sys.platform == cc.sys.WECHAT_GAME) {
|
|
||||||
const boundRoomId = window.getBoundRoomIdFromPersistentStorage();
|
|
||||||
const wxToShareMessage = {
|
|
||||||
title: '夺宝大作战',
|
|
||||||
imageUrl: 'https://mmocgame.qpic.cn/wechatgame/ibxA6JVNslX02zq6aAWCZiaWTXLYGorrVgUszo3WH1oL1CFDcFU7VKPRXPFiadxagMR/0',
|
|
||||||
imageUrlId: 'FiLZpa5FT5GgEeEagzGBsA',
|
|
||||||
query: 'expectedRoomId=' + boundRoomId,
|
|
||||||
};
|
|
||||||
console.warn("The boundRoomId for sharing: ", boundRoomId, " wxToShareMessage ", wxToShareMessage);
|
|
||||||
wx.showShareMenu();
|
|
||||||
wx.onShareAppMessage(() => (wxToShareMessage));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -73,11 +60,7 @@ cc.Class({
|
|||||||
exitBtnOnClick(evt) {
|
exitBtnOnClick(evt) {
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
||||||
window.closeWSConnection();
|
window.closeWSConnection();
|
||||||
if (cc.sys.platform == cc.sys.WECHAT_GAME) {
|
cc.director.loadScene('login');
|
||||||
cc.director.loadScene('wechatGameLogin');
|
|
||||||
} else {
|
|
||||||
cc.director.loadScene('login');
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updatePlayersInfo(playerMetas) {
|
updatePlayersInfo(playerMetas) {
|
||||||
@ -107,23 +90,7 @@ cc.Class({
|
|||||||
if (remoteUrl == null || remoteUrl == '') {
|
if (remoteUrl == null || remoteUrl == '') {
|
||||||
cc.log(`No avatar to show for :`);
|
cc.log(`No avatar to show for :`);
|
||||||
cc.log(playerMeta);
|
cc.log(playerMeta);
|
||||||
remoteUrl = 'http://wx.qlogo.cn/mmopen/PiajxSqBRaEJUWib5D85KXWHumaxhU4E9XOn9bUpCNKF3F4ibfOj8JYHCiaoosvoXCkTmOQE1r2AKKs8ObMaz76EdA/0'
|
|
||||||
}
|
}
|
||||||
cc.loader.load({
|
|
||||||
url: remoteUrl,
|
|
||||||
type: 'jpg'
|
|
||||||
}, function(err, texture) {
|
|
||||||
if (null != err ) {
|
|
||||||
console.error(err);
|
|
||||||
} else {
|
|
||||||
if (null == texture) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const sf = new cc.SpriteFrame();
|
|
||||||
sf.setTexture(texture);
|
|
||||||
playerInfoNode.getChildByName('avatarMask').getChildByName('avatar').getComponent(cc.Sprite).spriteFrame = sf;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function isEmptyString(str) {
|
function isEmptyString(str) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const i18n = require('LanguageData');
|
const i18n = require('LanguageData');
|
||||||
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
|
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
|
||||||
|
|
||||||
cc.Class({
|
cc.Class({
|
||||||
extends: cc.Component,
|
extends: cc.Component,
|
||||||
|
|
||||||
@ -59,11 +60,7 @@ cc.Class({
|
|||||||
loadingPrefab: {
|
loadingPrefab: {
|
||||||
default: null,
|
default: null,
|
||||||
type: cc.Prefab
|
type: cc.Prefab
|
||||||
},
|
}
|
||||||
wechatLoginTips: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Label,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// LIFE-CYCLE CALLBACKS:
|
// LIFE-CYCLE CALLBACKS:
|
||||||
@ -88,22 +85,18 @@ cc.Class({
|
|||||||
self.getRetCodeList();
|
self.getRetCodeList();
|
||||||
self.getRegexList();
|
self.getRegexList();
|
||||||
|
|
||||||
const isUsingX5BlinkKernelOrWebkitWeChatKernel = window.isUsingX5BlinkKernelOrWebkitWeChatKernel();
|
self.phoneNumberTips.active = true;
|
||||||
//const isUsingX5BlinkKernelOrWebkitWeChatKernel = true;
|
self.smsLoginCaptchaButton.active = true;
|
||||||
if (!CC_DEBUG) {
|
|
||||||
self.phoneNumberTips.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
|
||||||
self.smsLoginCaptchaButton.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
|
||||||
|
|
||||||
self.captchaTips.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
self.captchaTips.active = true;
|
||||||
self.phoneCountryCodeInput.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
self.phoneCountryCodeInput.active = true;
|
||||||
self.phoneNumberInput.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
self.phoneNumberInput.active = true;
|
||||||
self.smsLoginCaptchaInput.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
self.smsLoginCaptchaInput.active = true;
|
||||||
|
|
||||||
self.phoneLabel.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
self.phoneLabel.active = true;
|
||||||
self.smsLoginCaptchaLabel.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
self.smsLoginCaptchaLabel.active = true;
|
||||||
|
|
||||||
self.loginButton.active = !isUsingX5BlinkKernelOrWebkitWeChatKernel;
|
self.loginButton.active = true;
|
||||||
}
|
|
||||||
self.checkPhoneNumber = self.checkPhoneNumber.bind(self);
|
self.checkPhoneNumber = self.checkPhoneNumber.bind(self);
|
||||||
self.checkIntAuthTokenExpire = self.checkIntAuthTokenExpire.bind(self);
|
self.checkIntAuthTokenExpire = self.checkIntAuthTokenExpire.bind(self);
|
||||||
self.checkCaptcha = self.checkCaptcha.bind(self);
|
self.checkCaptcha = self.checkCaptcha.bind(self);
|
||||||
@ -124,15 +117,13 @@ cc.Class({
|
|||||||
cc.error(err.message || err);
|
cc.error(err.message || err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (false == (cc.sys.platform == cc.sys.WECHAT_GAME)) {
|
// Otherwise, `window.RoomDownsyncFrame` is already assigned.
|
||||||
// Otherwise, `window.RoomDownsyncFrame` is already assigned.
|
let protoRoot = new protobuf.Root;
|
||||||
let protoRoot = new protobuf.Root;
|
window.protobuf.parse(textAsset.text, protoRoot);
|
||||||
window.protobuf.parse(textAsset.text, protoRoot);
|
window.RoomDownsyncFrame = protoRoot.lookupType("treasurehunterx.RoomDownsyncFrame");
|
||||||
window.RoomDownsyncFrame = protoRoot.lookupType("treasurehunterx.RoomDownsyncFrame");
|
window.BattleColliderInfo = protoRoot.lookupType("treasurehunterx.BattleColliderInfo");
|
||||||
window.BattleColliderInfo = protoRoot.lookupType("treasurehunterx.BattleColliderInfo");
|
window.WsReq = protoRoot.lookupType("treasurehunterx.WsReq");
|
||||||
window.WsReq = protoRoot.lookupType("treasurehunterx.WsReq");
|
window.WsResp = protoRoot.lookupType("treasurehunterx.WsResp");
|
||||||
window.WsResp = protoRoot.lookupType("treasurehunterx.WsResp");
|
|
||||||
}
|
|
||||||
self.checkIntAuthTokenExpire().then(
|
self.checkIntAuthTokenExpire().then(
|
||||||
() => {
|
() => {
|
||||||
const intAuthToken = JSON.parse(cc.sys.localStorage.getItem('selfPlayer')).intAuthToken;
|
const intAuthToken = JSON.parse(cc.sys.localStorage.getItem('selfPlayer')).intAuthToken;
|
||||||
@ -140,19 +131,6 @@ cc.Class({
|
|||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
||||||
if ( (CC_DEBUG || isUsingX5BlinkKernelOrWebkitWeChatKernel) ) {
|
|
||||||
if (null != qDict && qDict["code"]) {
|
|
||||||
const code = qDict["code"];
|
|
||||||
console.log("Got the wx authcode: ", code, "while at full url: " + window.location.href);
|
|
||||||
self.useWXCodeLogin(code);
|
|
||||||
} else {
|
|
||||||
if (isUsingX5BlinkKernelOrWebkitWeChatKernel) {
|
|
||||||
self.getWechatCode(null);
|
|
||||||
} else {
|
|
||||||
// Deliberately left blank.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -355,46 +333,10 @@ cc.Class({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onWechatLoggedIn(res) {
|
|
||||||
const self = this;
|
|
||||||
if (res.ret === self.retCodeDict.OK) {
|
|
||||||
self.enableInteractiveControls(false);
|
|
||||||
const date = Number(res.expiresAt);
|
|
||||||
const selfPlayer = {
|
|
||||||
expiresAt: date,
|
|
||||||
playerId: res.playerId,
|
|
||||||
intAuthToken: res.intAuthToken,
|
|
||||||
displayName: res.displayName,
|
|
||||||
avatar: res.avatar,
|
|
||||||
}
|
|
||||||
cc.sys.localStorage.setItem('selfPlayer', JSON.stringify(selfPlayer));
|
|
||||||
|
|
||||||
const qDict = window.getQueryParamDict();
|
|
||||||
const expectedRoomId = qDict["expectedRoomId"];
|
|
||||||
if (null != expectedRoomId) {
|
|
||||||
console.log("onWechatLoggedIn using expectedRoomId == " + expectedRoomId);
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
}
|
|
||||||
// To remove "code=XXX" in "query string".
|
|
||||||
window.history.replaceState(qDict, null, window.location.pathname);
|
|
||||||
self.useTokenLogin(res.intAuthToken);
|
|
||||||
} else {
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
self.wechatLoginTips.string = constants.ALERT.TIP_LABEL.WECHAT_LOGIN_FAILS + ", errorCode = " + res.ret;
|
|
||||||
// To remove "code=XXX" in "query string".
|
|
||||||
window.history.replaceState({}, null, window.location.pathname);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onLoggedIn(res) {
|
onLoggedIn(res) {
|
||||||
const self = this;
|
const self = this;
|
||||||
cc.log(`OnLoggedIn ${JSON.stringify(res)}.`)
|
cc.log(`OnLoggedIn ${JSON.stringify(res)}.`)
|
||||||
if (res.ret === self.retCodeDict.OK) {
|
if (res.ret === self.retCodeDict.OK) {
|
||||||
if(window.isUsingX5BlinkKernelOrWebkitWeChatKernel()) {
|
|
||||||
window.initWxSdk = self.initWxSdk.bind(self);
|
|
||||||
window.initWxSdk();
|
|
||||||
}
|
|
||||||
self.enableInteractiveControls(false);
|
self.enableInteractiveControls(false);
|
||||||
const date = Number(res.expiresAt);
|
const date = Number(res.expiresAt);
|
||||||
const selfPlayer = {
|
const selfPlayer = {
|
||||||
@ -451,105 +393,4 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
useWXCodeLogin(_code) {
|
|
||||||
const self = this;
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
url: backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER + constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.WECHAT + constants.ROUTE_PATH.LOGIN,
|
|
||||||
type: "POST",
|
|
||||||
data: {
|
|
||||||
code: _code
|
|
||||||
},
|
|
||||||
success: function(res) {
|
|
||||||
self.onWechatLoggedIn(res);
|
|
||||||
},
|
|
||||||
error: function(xhr, status, errMsg) {
|
|
||||||
console.log("Login attempt `useWXCodeLogin` failed, about to execute `clearBoundRoomIdInBothVolatileAndPersistentStorage`.");
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
self.wechatLoginTips.string = constants.ALERT.TIP_LABEL.WECHAT_LOGIN_FAILS + ", errorMsg =" + errMsg;
|
|
||||||
window.history.replaceState({}, null, window.location.pathname);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getWechatCode(evt) {
|
|
||||||
let self = this;
|
|
||||||
self.wechatLoginTips.string = "";
|
|
||||||
const wechatServerEndpoint = wechatAddress.PROTOCOL + "://" + wechatAddress.HOST + ((null != wechatAddress.PORT && "" != wechatAddress.PORT.trim()) ? (":" + wechatAddress.PORT) : "");
|
|
||||||
const url = wechatServerEndpoint + constants.WECHAT.AUTHORIZE_PATH + "?" + wechatAddress.APPID_LITERAL + "&" + constants.WECHAT.REDIRECT_RUI_KEY + NetworkUtils.encode(window.location.href) + "&" + constants.WECHAT.RESPONSE_TYPE + "&" + constants.WECHAT.SCOPE + constants.WECHAT.FIN;
|
|
||||||
console.log("To visit wechat auth addr: " + url);
|
|
||||||
window.location.href = url;
|
|
||||||
},
|
|
||||||
|
|
||||||
initWxSdk() {
|
|
||||||
const selfPlayer = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
|
|
||||||
const origUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
|
||||||
/*
|
|
||||||
* The `shareLink` must
|
|
||||||
* - have its 2nd-order-domain registered as trusted 2nd-order under the targetd `res.jsConfig.app_id`, and
|
|
||||||
* - extracted from current window.location.href.
|
|
||||||
*/
|
|
||||||
const shareLink = origUrl;
|
|
||||||
const updateAppMsgShareDataObj = {
|
|
||||||
type: 'link', // 分享类型,music、video或link,不填默认为link
|
|
||||||
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
|
|
||||||
title: document.title, // 分享标题
|
|
||||||
desc: 'Let\'s play together!', // 分享描述
|
|
||||||
link: shareLink + (cc.sys.localStorage.getItem('boundRoomId') ? "" : ("?expectedRoomId=" + cc.sys.localStorage.getItem('boundRoomId'))),
|
|
||||||
imgUrl: origUrl + "/favicon.ico", // 分享图标
|
|
||||||
success: function() {
|
|
||||||
// 设置成功
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const menuShareTimelineObj = {
|
|
||||||
title: document.title, // 分享标题
|
|
||||||
link: shareLink + (cc.sys.localStorage.getItem('boundRoomId') ? "" : ("?expectedRoomId=" + cc.sys.localStorage.getItem('boundRoomId'))),
|
|
||||||
imgUrl: origUrl + "/favicon.ico", // 分享图标
|
|
||||||
success: function() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
const wxConfigUrl = (window.isUsingWebkitWechatKernel() ? window.atFirstLocationHref : window.location.href);
|
|
||||||
//接入微信登录接口
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
"url": backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER + constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.WECHAT + constants.ROUTE_PATH.JSCONFIG,
|
|
||||||
type: "POST",
|
|
||||||
data: {
|
|
||||||
"url": wxConfigUrl,
|
|
||||||
"intAuthToken": selfPlayer.intAuthToken,
|
|
||||||
},
|
|
||||||
success: function(res) {
|
|
||||||
if (constants.RET_CODE.OK != res.ret) {
|
|
||||||
console.log("cannot get the wsConfig. retCode == " + res.ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const jsConfig = res.jsConfig;
|
|
||||||
console.log(updateAppMsgShareDataObj);
|
|
||||||
const configData = {
|
|
||||||
debug: CC_DEBUG, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
|
|
||||||
appId: jsConfig.app_id, // 必填,公众号的唯一标识
|
|
||||||
timestamp: jsConfig.timestamp.toString(), // 必填,生成签名的时间戳
|
|
||||||
nonceStr: jsConfig.nonce_str, // 必填,生成签名的随机串
|
|
||||||
jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline'],
|
|
||||||
signature: jsConfig.signature, // 必填,签名
|
|
||||||
};
|
|
||||||
console.log("config url: " + wxConfigUrl);
|
|
||||||
console.log("wx.config: ");
|
|
||||||
console.log(configData);
|
|
||||||
wx.config(configData);
|
|
||||||
console.log("Current window.location.href: " + window.location.href);
|
|
||||||
wx.ready(function() {
|
|
||||||
console.log("Here is wx.ready.")
|
|
||||||
wx.onMenuShareAppMessage(updateAppMsgShareDataObj);
|
|
||||||
wx.onMenuShareTimeline(menuShareTimelineObj);
|
|
||||||
});
|
|
||||||
wx.error(function(res) {
|
|
||||||
console.error("wx config fails and error is " + JSON.stringify(res));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
error: function(xhr, status, errMsg) {
|
|
||||||
console.log("cannot get the wsConfig. errMsg == " + errMsg);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
const i18n = require('LanguageData');
|
const i18n = require('LanguageData');
|
||||||
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
|
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
|
||||||
|
|
||||||
|
const collisions = require('./modules/Collisions');
|
||||||
|
const RingBuffer = require('./RingBuffer');
|
||||||
|
|
||||||
window.ALL_MAP_STATES = {
|
window.ALL_MAP_STATES = {
|
||||||
VISUAL: 0, // For free dragging & zooming.
|
VISUAL: 0, // For free dragging & zooming.
|
||||||
EDITING_BELONGING: 1,
|
EDITING_BELONGING: 1,
|
||||||
@ -15,9 +18,11 @@ window.ALL_BATTLE_STATES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.MAGIC_ROOM_DOWNSYNC_FRAME_ID = {
|
window.MAGIC_ROOM_DOWNSYNC_FRAME_ID = {
|
||||||
BATTLE_READY_TO_START: -99,
|
|
||||||
PLAYER_ADDED_AND_ACKED: -98,
|
PLAYER_ADDED_AND_ACKED: -98,
|
||||||
PLAYER_READDED_AND_ACKED: -97,
|
PLAYER_READDED_AND_ACKED: -97,
|
||||||
|
|
||||||
|
BATTLE_READY_TO_START: -1,
|
||||||
|
BATTLE_START: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
cc.Class({
|
cc.Class({
|
||||||
@ -56,14 +61,6 @@ cc.Class({
|
|||||||
type: cc.Prefab,
|
type: cc.Prefab,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
polygonBoundaryShelterPrefab: {
|
|
||||||
type: cc.Prefab,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
polygonBoundaryShelterZReducerPrefab: {
|
|
||||||
type: cc.Prefab,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
keyboardInputControllerNode: {
|
keyboardInputControllerNode: {
|
||||||
type: cc.Node,
|
type: cc.Node,
|
||||||
default: null
|
default: null
|
||||||
@ -127,8 +124,9 @@ cc.Class({
|
|||||||
type: cc.Float,
|
type: cc.Float,
|
||||||
default: 1.0/60
|
default: 1.0/60
|
||||||
},
|
},
|
||||||
rollbackInMainUpdate: {
|
maxChasingRenderFramesPerUpdate: {
|
||||||
default: true
|
type: cc.Integer,
|
||||||
|
default: 10
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -136,27 +134,46 @@ cc.Class({
|
|||||||
return (0 == inputFrameId%10);
|
return (0 == inputFrameId%10);
|
||||||
},
|
},
|
||||||
|
|
||||||
_dumpToFullFrameCache: function(fullFrame) {
|
_dumpToRenderCache: function(roomDownsyncFrame) {
|
||||||
const self = this;
|
const self = this;
|
||||||
self.recentFrameCache.set(fullFrame.id, fullFrame);
|
const minToKeepRenderFrameId = self.lastAllConfirmedRenderFrameId;
|
||||||
if (fullFrame.id >= self.recentFrameCacheEd) {
|
while (0 < self.recentRenderCache.cnt && self.recentRenderCache.stFrameId < minToKeepRenderFrameId) {
|
||||||
// Should be consecutive
|
self.recentRenderCache.pop();
|
||||||
++self.recentFrameCacheEd;
|
|
||||||
}
|
}
|
||||||
while (self.recentFrameCacheEd - self.recentFrameCacheSt >= self.recentFrameCacheMaxCount) {
|
if (self.recentRenderCache.stFrameId < minToKeepRenderFrameId) {
|
||||||
self.recentFrameCache.delete(self.recentFrameCacheSt++);
|
console.warn("Weird dumping of RENDER frame: self.renderFrame=", self.renderFrame, ", self.recentInputCache=", self._stringifyRecentInputCache(false), ", self.recentRenderCache=", self._stringifyRecentRenderCache(false), ", self.lastAllConfirmedRenderFrameId=", self.lastAllConfirmedRenderFrameId, ", self.lastAllConfirmedInputFrameId=", self.lastAllConfirmedInputFrameId);
|
||||||
|
}
|
||||||
|
const existing = self.recentRenderCache.getByFrameId(roomDownsyncFrame.id);
|
||||||
|
if (null != existing) {
|
||||||
|
existing.players = roomDownsyncFrame.players;
|
||||||
|
existing.sentAt = roomDownsyncFrame.sentAt;
|
||||||
|
existing.countdownNanos = roomDownsyncFrame.countdownNanos;
|
||||||
|
existing.treasures = roomDownsyncFrame.treasures;
|
||||||
|
existing.bullets = roomDownsyncFrame.bullets;
|
||||||
|
existing.speedShoes = roomDownsyncFrame.speedShoes;
|
||||||
|
existing.guardTowers = roomDownsyncFrame.guardTowers;
|
||||||
|
existing.playerMetas = roomDownsyncFrame.playerMetas;
|
||||||
|
} else {
|
||||||
|
self.recentRenderCache.put(roomDownsyncFrame);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_dumpToInputCache: function(inputFrameDownsync) {
|
_dumpToInputCache: function(inputFrameDownsync) {
|
||||||
const self = this;
|
const self = this;
|
||||||
self.recentInputCache.set(inputFrameDownsync.inputFrameId, inputFrameDownsync);
|
let minToKeepInputFrameId = self._convertToInputFrameId(self.lastAllConfirmedRenderFrameId, self.inputDelayFrames); // [WARNING] This could be different from "self.lastAllConfirmedInputFrameId". We'd like to keep the corresponding inputFrame for "self.lastAllConfirmedRenderFrameId" such that a rollback could place "self.chaserRenderFrameId = self.lastAllConfirmedRenderFrameId" for the worst case incorrect prediction.
|
||||||
if (inputFrameDownsync.inputFrameId >= self.recentInputCacheEd) {
|
if (minToKeepInputFrameId > self.lastAllConfirmedInputFrameId) minToKeepInputFrameId = self.lastAllConfirmedInputFrameId;
|
||||||
// Should be consecutive
|
while (0 < self.recentInputCache.cnt && self.recentInputCache.stFrameId < minToKeepInputFrameId) {
|
||||||
++self.recentInputCacheEd;
|
self.recentInputCache.pop();
|
||||||
}
|
}
|
||||||
while (self.recentInputCacheEd - self.recentInputCacheSt >= self.recentInputCacheMaxCount) {
|
if (self.recentInputCache.stFrameId < minToKeepInputFrameId) {
|
||||||
self.recentInputCache.delete(self.recentInputCacheSt++);
|
console.warn("Weird dumping of INPUT frame: self.renderFrame=", self.renderFrame, ", self.recentInputCache=", self._stringifyRecentInputCache(false), ", self.recentRenderCache=", self._stringifyRecentRenderCache(false), ", self.lastAllConfirmedRenderFrameId=", self.lastAllConfirmedRenderFrameId, ", self.lastAllConfirmedInputFrameId=", self.lastAllConfirmedInputFrameId);
|
||||||
|
}
|
||||||
|
const existing = self.recentInputCache.getByFrameId(inputFrameDownsync.inputFrameId);
|
||||||
|
if (null != existing) {
|
||||||
|
existing.inputList = inputFrameDownsync.inputList;
|
||||||
|
existing.confirmedList = inputFrameDownsync.confirmedList;
|
||||||
|
} else {
|
||||||
|
self.recentInputCache.put(inputFrameDownsync);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -170,47 +187,40 @@ cc.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_shouldGenerateInputFrameUpsync(renderFrameId) {
|
_shouldGenerateInputFrameUpsync(renderFrameId) {
|
||||||
return ((renderFrameId & 3) == 0); // 3 is 0x0011
|
return ((renderFrameId & ((1 << this.inputScaleFrames)-1)) == 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_allConfirmed(confirmedList) {
|
||||||
|
return (confirmedList+1) == (1 << this.playerRichInfoDict.size);
|
||||||
|
},
|
||||||
|
|
||||||
_generateInputFrameUpsync(inputFrameId) {
|
_generateInputFrameUpsync(inputFrameId) {
|
||||||
const instance = this;
|
const self = this;
|
||||||
if (
|
if (
|
||||||
null == instance.ctrl ||
|
null == self.ctrl ||
|
||||||
null == instance.selfPlayerInfo
|
null == self.selfPlayerInfo
|
||||||
) {
|
) {
|
||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
const discreteDir = instance.ctrl.getDiscretizedDirection();
|
const joinIndex = self.selfPlayerInfo.joinIndex;
|
||||||
let prefabbedInputList = null;
|
const discreteDir = self.ctrl.getDiscretizedDirection();
|
||||||
let selfPlayerLastInputFrameInput = 0;
|
const previousInputFrameDownsyncWithPrediction = self.getCachedInputFrameDownsyncWithPrediction(inputFrameId);
|
||||||
if (0 == instance.recentInputCacheEd) {
|
const prefabbedInputList = (null == previousInputFrameDownsyncWithPrediction ? new Array(self.playerRichInfoDict.size).fill(0) : previousInputFrameDownsyncWithPrediction.inputList.slice());
|
||||||
prefabbedInputList = new Array(instance.playerRichInfoDict.size).fill(0);
|
prefabbedInputList[(joinIndex-1)] = discreteDir.encodedIdx;
|
||||||
} else {
|
const prefabbedInputFrameDownsync = {
|
||||||
if (!instance.recentInputCache.has(instance.recentInputCacheEd-1)) {
|
inputFrameId: inputFrameId,
|
||||||
console.warn("_generateInputFrameUpsync: recentInputCache is NOT having inputFrameId=", instance.recentInputCacheEd-1, "; recentInputCache=", instance._stringifyRecentInputCache(false));
|
inputList: prefabbedInputList,
|
||||||
prefabbedInputList = new Array(instance.playerRichInfoDict.size).fill(0);
|
confirmedList: (1 << (self.selfPlayerInfo.joinIndex-1))
|
||||||
} else {
|
|
||||||
prefabbedInputList = Array.from(instance.recentInputCache.get(instance.recentInputCacheEd-1).inputList);
|
|
||||||
selfPlayerLastInputFrameInput = prefabbedInputList[(instance.selfPlayerInfo.joinIndex-1)]; // it's an integer, thus making a copy here, not impacted by later assignments
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prefabbedInputList[(instance.selfPlayerInfo.joinIndex-1)] = discreteDir.encodedIdx;
|
|
||||||
|
|
||||||
const prefabbedInputFrameDownsync = {
|
|
||||||
inputFrameId: inputFrameId,
|
|
||||||
inputList: prefabbedInputList,
|
|
||||||
confirmedList: (1 << (instance.selfPlayerInfo.joinIndex-1))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
instance._dumpToInputCache(prefabbedInputFrameDownsync); // A prefabbed inputFrame, would certainly be adding a new inputFrame to the cache, because server only downsyncs "all-confirmed inputFrames"
|
self._dumpToInputCache(prefabbedInputFrameDownsync); // A prefabbed inputFrame, would certainly be adding a new inputFrame to the cache, because server only downsyncs "all-confirmed inputFrames"
|
||||||
|
|
||||||
return [selfPlayerLastInputFrameInput, discreteDir.encodedIdx];
|
const previousSelfInput = (null == previousInputFrameDownsyncWithPrediction ? null : previousInputFrameDownsyncWithPrediction.inputList[joinIndex-1]);
|
||||||
|
return [previousSelfInput, discreteDir.encodedIdx];
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldSendInputFrameUpsyncBatch(prevSelfInput, currSelfInput, lastUpsyncInputFrameId, currInputFrameId) {
|
shouldSendInputFrameUpsyncBatch(prevSelfInput, currSelfInput, lastUpsyncInputFrameId, currInputFrameId) {
|
||||||
/*
|
/*
|
||||||
For a 2-player-battle, this "shouldUpsyncForEarlyAllConfirmedOnServer" can be omitted, however for more players in a same battle, to avoid a "long time non-moving player" jamming the downsync of other moving players, we should use this flag.
|
For a 2-player-battle, this "shouldUpsyncForEarlyAllConfirmedOnServer" can be omitted, however for more players in a same battle, to avoid a "long time non-moving player" jamming the downsync of other moving players, we should use this flag.
|
||||||
*/
|
*/
|
||||||
@ -219,33 +229,33 @@ cc.Class({
|
|||||||
return shouldUpsyncForEarlyAllConfirmedOnServer || (prevSelfInput != currSelfInput);
|
return shouldUpsyncForEarlyAllConfirmedOnServer || (prevSelfInput != currSelfInput);
|
||||||
},
|
},
|
||||||
|
|
||||||
_sendInputFrameUpsyncBatch(inputFrameId) {
|
sendInputFrameUpsyncBatch(inputFrameId) {
|
||||||
// [WARNING] Why not just send the latest input? Because different player would have a different "inputFrameId" of changing its last input, and that could make the server not recognizing any "all-confirmed inputFrame"!
|
// [WARNING] Why not just send the latest input? Because different player would have a different "inputFrameId" of changing its last input, and that could make the server not recognizing any "all-confirmed inputFrame"!
|
||||||
const instance = this;
|
const self = this;
|
||||||
let inputFrameUpsyncBatch = [];
|
let inputFrameUpsyncBatch = [];
|
||||||
for (let i = instance.lastUpsyncInputFrameId+1; i <= inputFrameId; ++i) {
|
for (let i = self.lastUpsyncInputFrameId+1; i <= inputFrameId; ++i) {
|
||||||
const inputFrameDownsync = instance.recentInputCache.get(i);
|
const inputFrameDownsync = self.recentInputCache.getByFrameId(i);
|
||||||
if (null == inputFrameDownsync) {
|
if (null == inputFrameDownsync) {
|
||||||
console.warn("_sendInputFrameUpsyncBatch: recentInputCache is NOT having inputFrameId=", i, "; recentInputCache=", instance._stringifyRecentInputCache(false));
|
console.warn("sendInputFrameUpsyncBatch: recentInputCache is NOT having inputFrameId=", i, "; recentInputCache=", self._stringifyRecentInputCache(false));
|
||||||
} else {
|
} else {
|
||||||
const inputFrameUpsync = {
|
const inputFrameUpsync = {
|
||||||
inputFrameId: i,
|
inputFrameId: i,
|
||||||
encodedDir: inputFrameDownsync.inputList[instance.selfPlayerInfo.joinIndex-1],
|
encodedDir: inputFrameDownsync.inputList[self.selfPlayerInfo.joinIndex-1],
|
||||||
};
|
};
|
||||||
inputFrameUpsyncBatch.push(inputFrameUpsync);
|
inputFrameUpsyncBatch.push(inputFrameUpsync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const reqData = window.WsReq.encode({
|
const reqData = window.WsReq.encode({
|
||||||
msgId: Date.now(),
|
msgId: Date.now(),
|
||||||
playerId: instance.selfPlayerInfo.id,
|
playerId: self.selfPlayerInfo.id,
|
||||||
act: window.UPSYNC_MSG_ACT_PLAYER_CMD,
|
act: window.UPSYNC_MSG_ACT_PLAYER_CMD,
|
||||||
joinIndex: instance.selfPlayerInfo.joinIndex,
|
joinIndex: self.selfPlayerInfo.joinIndex,
|
||||||
ackingFrameId: instance.lastRoomDownsyncFrameId,
|
ackingFrameId: self.lastAllConfirmedRenderFrameId,
|
||||||
ackingInputFrameId: instance.lastDownsyncInputFrameId,
|
ackingInputFrameId: self.lastAllConfirmedInputFrameId,
|
||||||
inputFrameUpsyncBatch: inputFrameUpsyncBatch,
|
inputFrameUpsyncBatch: inputFrameUpsyncBatch,
|
||||||
}).finish();
|
}).finish();
|
||||||
window.sendSafely(reqData);
|
window.sendSafely(reqData);
|
||||||
instance.lastUpsyncInputFrameId = inputFrameId;
|
self.lastUpsyncInputFrameId = inputFrameId;
|
||||||
},
|
},
|
||||||
|
|
||||||
onEnable() {
|
onEnable() {
|
||||||
@ -274,9 +284,6 @@ cc.Class({
|
|||||||
if (null != window.handleClientSessionCloseOrError) {
|
if (null != window.handleClientSessionCloseOrError) {
|
||||||
window.handleClientSessionCloseOrError = null;
|
window.handleClientSessionCloseOrError = null;
|
||||||
}
|
}
|
||||||
if (self.inputControlTimer) {
|
|
||||||
clearInterval(self.inputControlTimer);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
popupSimplePressToGo(labelString, hideYesButton) {
|
popupSimplePressToGo(labelString, hideYesButton) {
|
||||||
@ -323,6 +330,7 @@ cc.Class({
|
|||||||
self.countdownNanos = null;
|
self.countdownNanos = null;
|
||||||
|
|
||||||
// Clearing previous info of all players. [BEGINS]
|
// Clearing previous info of all players. [BEGINS]
|
||||||
|
self.collisionPlayerIndexPrefix = (1 << 17); // For tracking the movements of players
|
||||||
if (null != self.playerRichInfoDict) {
|
if (null != self.playerRichInfoDict) {
|
||||||
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
||||||
if (playerRichInfo.node.parent) {
|
if (playerRichInfo.node.parent) {
|
||||||
@ -333,27 +341,27 @@ cc.Class({
|
|||||||
self.playerRichInfoDict = new Map();
|
self.playerRichInfoDict = new Map();
|
||||||
// Clearing previous info of all players. [ENDS]
|
// Clearing previous info of all players. [ENDS]
|
||||||
|
|
||||||
self.lastRoomDownsyncFrameId = 0;
|
|
||||||
self.renderFrameId = 0; // After battle started
|
self.renderFrameId = 0; // After battle started
|
||||||
|
self.lastAllConfirmedRenderFrameId = -1;
|
||||||
|
self.lastAllConfirmedInputFrameId = -1;
|
||||||
|
self.chaserRenderFrameId = -1; // at any moment, "lastAllConfirmedRenderFrameId <= chaserRenderFrameId <= renderFrameId", but "chaserRenderFrameId" would fluctuate according to "handleInputFrameDownsyncBatch"
|
||||||
|
|
||||||
self.inputDelayFrames = 8;
|
self.inputDelayFrames = 8;
|
||||||
self.inputScaleFrames = 2;
|
self.inputScaleFrames = 2;
|
||||||
self.lastDownsyncInputFrameId = -1;
|
|
||||||
self.lastAllConfirmedInputFrameId = -1;
|
|
||||||
self.lastUpsyncInputFrameId = -1;
|
self.lastUpsyncInputFrameId = -1;
|
||||||
self.inputFrameUpsyncDelayTolerance = 2;
|
self.inputFrameUpsyncDelayTolerance = 2;
|
||||||
|
|
||||||
self.recentFrameCache = new Map();
|
self.recentRenderCache = new RingBuffer(1024);
|
||||||
self.recentFrameCacheSt = 0; // closed index
|
|
||||||
self.recentFrameCacheEd = 0; // open index
|
|
||||||
self.recentFrameCacheMaxCount = 1024;
|
|
||||||
|
|
||||||
self.selfPlayerInfo = null; // This field is kept for distinguishing "self" and "others".
|
self.selfPlayerInfo = null; // This field is kept for distinguishing "self" and "others".
|
||||||
self.recentInputCache = new Map(); // TODO: Use a ringbuf instead
|
self.recentInputCache = new RingBuffer(1024);
|
||||||
self.recentInputCacheSt = 0; // closed index
|
|
||||||
self.recentInputCacheEd = 0; // open index
|
self.latestCollisionSys = new collisions.Collisions();
|
||||||
self.recentInputCacheMaxCount = 1024;
|
self.chaserCollisionSys = new collisions.Collisions();
|
||||||
self.toRollbackRenderFrameId1 = null;
|
|
||||||
self.toRollbackInputFrameId1 = null;
|
self.collisionBarrierIndexPrefix = (1 << 16); // For tracking the movements of barriers, though not yet actually used
|
||||||
|
self.latestCollisionSysMap = new Map();
|
||||||
|
self.chaserCollisionSysMap = new Map();
|
||||||
|
|
||||||
self.transitToState(ALL_MAP_STATES.VISUAL);
|
self.transitToState(ALL_MAP_STATES.VISUAL);
|
||||||
|
|
||||||
@ -386,8 +394,7 @@ cc.Class({
|
|||||||
|
|
||||||
const mapNode = self.node;
|
const mapNode = self.node;
|
||||||
const canvasNode = mapNode.parent;
|
const canvasNode = mapNode.parent;
|
||||||
cc.director.getCollisionManager().enabled = true;
|
cc.director.getCollisionManager().enabled = false;
|
||||||
cc.director.getCollisionManager().enabledDebugDraw = CC_DEBUG;
|
|
||||||
// self.musicEffectManagerScriptIns = self.node.getComponent("MusicEffectManager");
|
// self.musicEffectManagerScriptIns = self.node.getComponent("MusicEffectManager");
|
||||||
self.musicEffectManagerScriptIns = null;
|
self.musicEffectManagerScriptIns = null;
|
||||||
|
|
||||||
@ -443,8 +450,6 @@ cc.Class({
|
|||||||
self.clientUpsyncFps = 60;
|
self.clientUpsyncFps = 60;
|
||||||
|
|
||||||
window.handleBattleColliderInfo = function(parsedBattleColliderInfo) {
|
window.handleBattleColliderInfo = function(parsedBattleColliderInfo) {
|
||||||
console.log(parsedBattleColliderInfo);
|
|
||||||
|
|
||||||
self.battleColliderInfo = parsedBattleColliderInfo;
|
self.battleColliderInfo = parsedBattleColliderInfo;
|
||||||
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
||||||
|
|
||||||
@ -459,11 +464,8 @@ cc.Class({
|
|||||||
[WARNING]
|
[WARNING]
|
||||||
|
|
||||||
- The order of the following statements is important, because we should have finished "_resetCurrentMatch" before the first "RoomDownsyncFrame".
|
- The order of the following statements is important, because we should have finished "_resetCurrentMatch" before the first "RoomDownsyncFrame".
|
||||||
- It's important to assign new "tmxAsset" before "extractBoundaryObjects => initMapNodeByTiledBoundaries", to ensure that the correct tilesets are used.
|
- It's important to assign new "tmxAsset" before "extractBoundaryObjects", to ensure that the correct tilesets are used.
|
||||||
- To ensure clearance, put destruction of the "cc.TiledMap" component preceding that of "mapNode.destroyAllChildren()".
|
- To ensure clearance, put destruction of the "cc.TiledMap" component preceding that of "mapNode.destroyAllChildren()".
|
||||||
|
|
||||||
-- YFLu, 2019-09-07
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tiledMapIns.tmxAsset = null;
|
tiledMapIns.tmxAsset = null;
|
||||||
@ -485,9 +487,22 @@ cc.Class({
|
|||||||
singleImageLayer.node.opacity = 0;
|
singleImageLayer.node.opacity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let barrierIdCounter = 0;
|
||||||
const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node);
|
const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node);
|
||||||
tileCollisionManager.initMapNodeByTiledBoundaries(self, mapNode, boundaryObjs);
|
for (let boundaryObj of boundaryObjs.barriers) {
|
||||||
|
const x0 = boundaryObj[0].x, y0 = boundaryObj[0].y;
|
||||||
|
let pts = [];
|
||||||
|
// TODO: Simplify this redundant coordinate conversion within "extractBoundaryObjects", but since this routine is only called once per battle, not urgent.
|
||||||
|
for (let i = 0; i < boundaryObj.length; ++i) {
|
||||||
|
pts.push([boundaryObj[i].x-x0, boundaryObj[i].y-y0]);
|
||||||
|
}
|
||||||
|
const newBarrierLatest = self.latestCollisionSys.createPolygon(x0, y0, pts);
|
||||||
|
const newBarrierChaser = self.chaserCollisionSys.createPolygon(x0, y0, pts);
|
||||||
|
++barrierIdCounter;
|
||||||
|
const collisionBarrierIndex = (self.collisionBarrierIndexPrefix + barrierIdCounter);
|
||||||
|
self.latestCollisionSysMap.set(collisionBarrierIndex, newBarrierLatest);
|
||||||
|
self.chaserCollisionSysMap.set(collisionBarrierIndex, newBarrierChaser);
|
||||||
|
}
|
||||||
|
|
||||||
self.selfPlayerInfo = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
|
self.selfPlayerInfo = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
|
||||||
Object.assign(self.selfPlayerInfo, {
|
Object.assign(self.selfPlayerInfo, {
|
||||||
@ -524,61 +539,40 @@ cc.Class({
|
|||||||
self.transitToState(ALL_MAP_STATES.WAITING);
|
self.transitToState(ALL_MAP_STATES.WAITING);
|
||||||
self._inputControlEnabled = false;
|
self._inputControlEnabled = false;
|
||||||
|
|
||||||
let findingPlayerScriptIns = null;
|
let findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
||||||
window.handleRoomDownsyncFrame = function(rdf) {
|
window.handleRoomDownsyncFrame = function(rdf) {
|
||||||
if (ALL_BATTLE_STATES.WAITING != self.battleState
|
if (ALL_BATTLE_STATES.WAITING != self.battleState
|
||||||
&& ALL_BATTLE_STATES.IN_BATTLE != self.battleState
|
&& ALL_BATTLE_STATES.IN_BATTLE != self.battleState
|
||||||
&& ALL_BATTLE_STATES.IN_SETTLEMENT != self.battleState) {
|
&& ALL_BATTLE_STATES.IN_SETTLEMENT != self.battleState) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const frameId = rdf.id;
|
||||||
// Right upon establishment of the "PersistentSessionClient", we should receive an initial signal "BattleColliderInfo" earlier than any "RoomDownsyncFrame" containing "PlayerMeta" data.
|
// Right upon establishment of the "PersistentSessionClient", we should receive an initial signal "BattleColliderInfo" earlier than any "RoomDownsyncFrame" containing "PlayerMeta" data.
|
||||||
const refFrameId = rdf.refFrameId;
|
const refFrameId = rdf.refFrameId;
|
||||||
switch (refFrameId) {
|
switch (refFrameId) {
|
||||||
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_READY_TO_START:
|
|
||||||
// 显示倒计时
|
|
||||||
self.playersMatched(rdf.playerMetas);
|
|
||||||
// 隐藏返回按钮
|
|
||||||
findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
|
||||||
findingPlayerScriptIns.hideExitButton();
|
|
||||||
return;
|
|
||||||
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.PLAYER_ADDED_AND_ACKED:
|
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.PLAYER_ADDED_AND_ACKED:
|
||||||
self._initPlayerRichInfoDict(rdf.players, rdf.playerMetas);
|
// Update the "finding player" GUI and show it if not previously present
|
||||||
// 显示匹配玩家
|
|
||||||
findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
|
||||||
if (!self.findingPlayerNode.parent) {
|
if (!self.findingPlayerNode.parent) {
|
||||||
self.showPopupInCanvas(self.findingPlayerNode);
|
self.showPopupInCanvas(self.findingPlayerNode);
|
||||||
}
|
}
|
||||||
findingPlayerScriptIns.updatePlayersInfo(rdf.playerMetas);
|
findingPlayerScriptIns.updatePlayersInfo(rdf.playerMetas);
|
||||||
return;
|
return;
|
||||||
|
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_READY_TO_START:
|
||||||
|
self.onBattleReadyToStart(rdf.playerMetas, false);
|
||||||
|
return;
|
||||||
|
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START:
|
||||||
|
self.onBattleStarted(rdf);
|
||||||
|
return;
|
||||||
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.PLAYER_READDED_AND_ACKED:
|
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.PLAYER_READDED_AND_ACKED:
|
||||||
self._initPlayerRichInfoDict(rdf.players, rdf.playerMetas);
|
// [WARNING] The "frameId" from server could be quite fast-forwarding, don't assign it in other cases.
|
||||||
// In this case, we're definitely in an active battle, thus the "self.findingPlayerNode" should be hidden if being presented.
|
self.renderFrameId = frameId;
|
||||||
if (self.findingPlayerNode && self.findingPlayerNode.parent) {
|
self.lastAllConfirmedRenderFrameId = frameId;
|
||||||
self.findingPlayerNode.parent.removeChild(self.findingPlayerNode);
|
self.onBattleReadyToStart(rdf.playerMetas, true);
|
||||||
self.transitToState(ALL_MAP_STATES.VISUAL);
|
self.onBattleStarted(rdf);
|
||||||
if (self.playersInfoNode) {
|
|
||||||
for (let playerId in rdf.playerMetas) {
|
|
||||||
const playerMeta = rdf.playerMetas[playerId];
|
|
||||||
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
|
|
||||||
playersInfoScriptIns.updateData(playerMeta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const frameId = rdf.id;
|
|
||||||
if (0 == self.lastRoomDownsyncFrameId) {
|
|
||||||
if (1 == frameId) {
|
|
||||||
// No need to prompt upon rejoined.
|
|
||||||
self.popupSimplePressToGo(i18n.t("gameTip.start"));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.onBattleStarted(rdf);
|
|
||||||
}
|
|
||||||
|
|
||||||
self._dumpToFullFrameCache(rdf);
|
|
||||||
self.lastRoomDownsyncFrameId = frameId;
|
|
||||||
// TODO: Inject a NetworkDoctor as introduced in https://app.yinxiang.com/shard/s61/nl/13267014/5c575124-01db-419b-9c02-ec81f78c6ddc/.
|
// TODO: Inject a NetworkDoctor as introduced in https://app.yinxiang.com/shard/s61/nl/13267014/5c575124-01db-419b-9c02-ec81f78c6ddc/.
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -588,13 +582,13 @@ cc.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log("Received inputFrameDownsyncBatch=", batch, ", now correspondingLastLocalInputFrame=", self.recentInputCache.get(batch[batch.length-1].inputFrameId));
|
// console.log("Received inputFrameDownsyncBatch=", batch, ", now correspondingLastLocalInputFrame=", self.recentInputCache.getByFrameId(batch[batch.length-1].inputFrameId));
|
||||||
let firstPredictedYetIncorrectInputFrameId = null;
|
let firstPredictedYetIncorrectInputFrameId = null;
|
||||||
let firstPredictedYetIncorrectInputFrameJoinIndex = null;
|
let firstPredictedYetIncorrectInputFrameJoinIndex = null;
|
||||||
for (let k in batch) {
|
for (let k in batch) {
|
||||||
const inputFrameDownsync = batch[k];
|
const inputFrameDownsync = batch[k];
|
||||||
const inputFrameDownsyncId = inputFrameDownsync.inputFrameId;
|
const inputFrameDownsyncId = inputFrameDownsync.inputFrameId;
|
||||||
const localInputFrame = self.recentInputCache.get(inputFrameDownsyncId);
|
const localInputFrame = self.recentInputCache.getByFrameId(inputFrameDownsyncId);
|
||||||
if (null == localInputFrame) {
|
if (null == localInputFrame) {
|
||||||
console.warn("handleInputFrameDownsyncBatch: recentInputCache is NOT having inputFrameDownsyncId=", inputFrameDownsyncId, "; now recentInputCache=", self._stringifyRecentInputCache(false));
|
console.warn("handleInputFrameDownsyncBatch: recentInputCache is NOT having inputFrameDownsyncId=", inputFrameDownsyncId, "; now recentInputCache=", self._stringifyRecentInputCache(false));
|
||||||
} else {
|
} else {
|
||||||
@ -608,34 +602,36 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.lastAllConfirmedInputFrameId = inputFrameDownsyncId;
|
||||||
self._dumpToInputCache(inputFrameDownsync);
|
self._dumpToInputCache(inputFrameDownsync);
|
||||||
// [WARNING] Currently "lastDownsyncInputFrameId" and "lastAllConfirmedInputFrameId" are identical, but they (their definitions) are prone to changes in the future
|
|
||||||
self.lastDownsyncInputFrameId = inputFrameDownsyncId;
|
|
||||||
self.lastAllConfirmedInputFrameId = inputFrameDownsyncId; // TODO: Should localInputFrameId > self.lastAllConfirmedInputFrameId be corrected for their predictions on the other players?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null != firstPredictedYetIncorrectInputFrameId) {
|
if (null != firstPredictedYetIncorrectInputFrameId) {
|
||||||
const renderFrameId2 = self.renderFrameId;
|
|
||||||
const inputFrameId2 = self._convertToInputFrameId(renderFrameId2, self.inputDelayFrames);
|
|
||||||
const inputFrameId1 = firstPredictedYetIncorrectInputFrameId;
|
const inputFrameId1 = firstPredictedYetIncorrectInputFrameId;
|
||||||
const renderFrameId1 = self._convertToRenderFrameId(inputFrameId1, self.inputDelayFrames); // a.k.a. "firstRenderFrameIdUsingIncorrectInputFrameId"
|
const renderFrameId1 = self._convertToRenderFrameId(inputFrameId1, self.inputDelayFrames); // a.k.a. "firstRenderFrameIdUsingIncorrectInputFrameId"
|
||||||
if (renderFrameId1 < renderFrameId2) {
|
if (renderFrameId1 < self.renderFrameId) {
|
||||||
// No need to rollback when "renderFrameId1 == renderFrameId2", because the "delayedInputFrame for renderFrameId2" is not yet executed by now, it just went through "++self.renderFrameId" in "update(dt)" and js-runtime is mostly single-threaded in our programmable range.
|
/*
|
||||||
console.warn("Mismatched input detected!: [inputFrameId1:", inputFrameId1, ", inputFrameId2:", inputFrameId2, "), [renderFrameId1:", renderFrameId1, ", renderFrameId2:", renderFrameId2, "). ");
|
A typical case is as follows.
|
||||||
if (true == self.rollbackInMainUpdate) {
|
--------------------------------------------------------
|
||||||
// The actual rollback-and-replay would later be executed in update(dt).
|
[self.lastAllConfirmedRenderFrameId] : 22
|
||||||
if (null == self.toRollbackRenderFrameId1) {
|
|
||||||
self.toRollbackRenderFrameId1 = renderFrameId1;
|
|
||||||
self.toRollbackInputFrameId1 = inputFrameId1;
|
|
||||||
} else {
|
|
||||||
// Deliberately left blank. This case merely extends the ending indices
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self._rollbackAndReplay(inputFrameId1, renderFrameId1, inputFrameId2, renderFrameId2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
<renderFrameId1> : 36
|
||||||
|
|
||||||
|
|
||||||
|
<self.chaserRenderFrameId> : 62
|
||||||
|
|
||||||
|
[self.renderFrameId] : 64
|
||||||
|
--------------------------------------------------------
|
||||||
|
*/
|
||||||
|
if (renderFrameId1 < self.chaserRenderFrameId) {
|
||||||
|
// The actual rollback-and-chase would later be executed in update(dt).
|
||||||
|
console.warn("Mismatched input detected, resetting chaserRenderFrameId: inputFrameId1:", inputFrameId1, ", renderFrameId1:", renderFrameId1, ", chaserRenderFrameId before reset: ", self.chaserRenderFrameId);
|
||||||
|
self.chaserRenderFrameId = renderFrameId1;
|
||||||
|
} else {
|
||||||
|
// Deliberately left blank, chasing is ongoing.
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("Mismatched input yet no rollback needed: [inputFrameId1:", inputFrameId1, ", inputFrameId2:", inputFrameId2, "), [renderFrameId1:", renderFrameId1, ", renderFrameId2:", renderFrameId2, "). ");
|
// No need to rollback when "renderFrameId1 == self.renderFrameId", because the "corresponding delayedInputFrame for renderFrameId2" is NOT YET EXECUTED BY NOW, it just went through "++self.renderFrameId" in "update(dt)" and javascript-runtime is mostly single-threaded in our programmable range.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -695,10 +691,19 @@ cc.Class({
|
|||||||
|
|
||||||
onBattleStarted(rdf) {
|
onBattleStarted(rdf) {
|
||||||
// This function is also applicable to "re-joining".
|
// This function is also applicable to "re-joining".
|
||||||
const players = rdf.players;
|
|
||||||
const playerMetas = rdf.playerMetas;
|
|
||||||
console.log('On battle started!');
|
console.log('On battle started!');
|
||||||
const self = window.mapIns;
|
const self = window.mapIns;
|
||||||
|
const players = rdf.players;
|
||||||
|
const playerMetas = rdf.playerMetas;
|
||||||
|
self._initPlayerRichInfoDict(players, playerMetas);
|
||||||
|
|
||||||
|
// Show the top status indicators for IN_BATTLE
|
||||||
|
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
|
||||||
|
for (let i in playerMetas) {
|
||||||
|
const playerMeta = playerMetas[i];
|
||||||
|
playersInfoScriptIns.updateData(playerMeta);
|
||||||
|
}
|
||||||
|
|
||||||
if (null != rdf.countdownNanos) {
|
if (null != rdf.countdownNanos) {
|
||||||
self.countdownNanos = rdf.countdownNanos;
|
self.countdownNanos = rdf.countdownNanos;
|
||||||
}
|
}
|
||||||
@ -712,19 +717,24 @@ cc.Class({
|
|||||||
self.countdownToBeginGameNode.parent.removeChild(self.countdownToBeginGameNode);
|
self.countdownToBeginGameNode.parent.removeChild(self.countdownToBeginGameNode);
|
||||||
}
|
}
|
||||||
self.transitToState(ALL_MAP_STATES.VISUAL);
|
self.transitToState(ALL_MAP_STATES.VISUAL);
|
||||||
|
self.chaserRenderFrameId = rdf.id;
|
||||||
self._applyRoomDownsyncFrameDynamics(rdf);
|
self.applyRoomDownsyncFrameDynamics(rdf);
|
||||||
|
self._dumpToRenderCache(rdf);
|
||||||
self.battleState = ALL_BATTLE_STATES.IN_BATTLE; // Starts the increment of "self.renderFrameId" in "self.update(dt)"
|
self.battleState = ALL_BATTLE_STATES.IN_BATTLE; // Starts the increment of "self.renderFrameId" in "self.update(dt)"
|
||||||
|
if (null != window.boundRoomId) {
|
||||||
|
self.boundRoomIdLabel.string = window.boundRoomId;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
logBattleStats() {
|
logBattleStats() {
|
||||||
const self = this;
|
const self = this;
|
||||||
let s = [];
|
let s = [];
|
||||||
s.push("Battle stats: lastUpsyncInputFrameId=" + self.lastUpsyncInputFrameId + ", lastDownsyncInputFrameId=" + self.lastDownsyncInputFrameId + ", lastAllConfirmedInputFrameId=" + self.lastAllConfirmedInputFrameId);
|
s.push("Battle stats: lastUpsyncInputFrameId=" + self.lastUpsyncInputFrameId + ", lastAllConfirmedInputFrameId=" + self.lastAllConfirmedInputFrameId);
|
||||||
|
|
||||||
self.recentInputCache.forEach((inputFrameDownsync, inputFrameId) => {
|
for (let i = self.recentInputCache.stFrameId; i < self.recentInputCache.edFrameId; ++i) {
|
||||||
|
const inputFrameDownsync = self.recentInputCache.getByFrameId(i);
|
||||||
s.push(JSON.stringify(inputFrameDownsync));
|
s.push(JSON.stringify(inputFrameDownsync));
|
||||||
});
|
}
|
||||||
|
|
||||||
console.log(s.join('\n'));
|
console.log(s.join('\n'));
|
||||||
},
|
},
|
||||||
@ -749,12 +759,19 @@ cc.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
spawnPlayerNode(joinIndex, x, y) {
|
spawnPlayerNode(joinIndex, x, y) {
|
||||||
const instance = this;
|
const self = this;
|
||||||
const newPlayerNode = 1 == joinIndex ? cc.instantiate(instance.player1Prefab) : cc.instantiate(instance.player2Prefab); // hardcoded for now, car color determined solely by joinIndex
|
const newPlayerNode = 1 == joinIndex ? cc.instantiate(self.player1Prefab) : cc.instantiate(self.player2Prefab); // hardcoded for now, car color determined solely by joinIndex
|
||||||
newPlayerNode.setPosition(cc.v2(x, y));
|
newPlayerNode.setPosition(cc.v2(x, y));
|
||||||
newPlayerNode.getComponent("SelfPlayer").mapNode = instance.node;
|
newPlayerNode.getComponent("SelfPlayer").mapNode = self.node;
|
||||||
|
const currentSelfColliderCircle = newPlayerNode.getComponent(cc.CircleCollider);
|
||||||
|
|
||||||
safelyAddChild(instance.node, newPlayerNode);
|
const newPlayerColliderLatest = self.latestCollisionSys.createCircle(x, y, currentSelfColliderCircle.radius);
|
||||||
|
const newPlayerColliderChaser = self.chaserCollisionSys.createCircle(x, y, currentSelfColliderCircle.radius);
|
||||||
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
|
self.latestCollisionSysMap.set(collisionPlayerIndex, newPlayerColliderLatest);
|
||||||
|
self.chaserCollisionSysMap.set(collisionPlayerIndex, newPlayerColliderChaser);
|
||||||
|
|
||||||
|
safelyAddChild(self.node, newPlayerNode);
|
||||||
setLocalZOrder(newPlayerNode, 5);
|
setLocalZOrder(newPlayerNode, 5);
|
||||||
|
|
||||||
newPlayerNode.active = true;
|
newPlayerNode.active = true;
|
||||||
@ -766,72 +783,60 @@ cc.Class({
|
|||||||
|
|
||||||
update(dt) {
|
update(dt) {
|
||||||
const self = this;
|
const self = this;
|
||||||
try {
|
if (ALL_BATTLE_STATES.IN_BATTLE == self.battleState) {
|
||||||
if (ALL_BATTLE_STATES.IN_BATTLE == self.battleState) {
|
try {
|
||||||
let prevSelfInput = null, currSelfInput = null;
|
let prevSelfInput = null, currSelfInput = null;
|
||||||
const noDelayInputFrameId = self._convertToInputFrameId(self.renderFrameId, 0); // It's important that "inputDelayFrames == 0" here
|
const noDelayInputFrameId = self._convertToInputFrameId(self.renderFrameId, 0); // It's important that "inputDelayFrames == 0" here
|
||||||
if (self._shouldGenerateInputFrameUpsync(self.renderFrameId)) {
|
if (self._shouldGenerateInputFrameUpsync(self.renderFrameId)) {
|
||||||
const prevAndCurrInputs = self._generateInputFrameUpsync(noDelayInputFrameId);
|
const prevAndCurrInputs = self._generateInputFrameUpsync(noDelayInputFrameId);
|
||||||
prevSelfInput = prevAndCurrInputs[0];
|
prevSelfInput = prevAndCurrInputs[0];
|
||||||
currSelfInput = prevAndCurrInputs[1];
|
currSelfInput = prevAndCurrInputs[1];
|
||||||
}
|
|
||||||
if (self._shouldSendInputFrameUpsyncBatch(prevSelfInput, currSelfInput, self.lastUpsyncInputFrameId, noDelayInputFrameId)) {
|
|
||||||
// TODO: Is the following statement run asynchronously in an implicit manner? Should I explicitly run it asynchronously?
|
|
||||||
self._sendInputFrameUpsyncBatch(noDelayInputFrameId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const delayedInputFrameId = self._convertToInputFrameId(self.renderFrameId, self.inputDelayFrames); // The "inputFrameId" to use at current "renderFrameId"
|
|
||||||
if (true == self.rollbackInMainUpdate) {
|
|
||||||
if (null != self.toRollbackRenderFrameId1) {
|
|
||||||
// Rollback-and-replay if necessary, prior to applying the latest dynamics
|
|
||||||
const anotherJoinIndex = 3-self.selfPlayerInfo.joinIndex;
|
|
||||||
self._rollbackAndReplay(self.toRollbackInputFrameId1, self.toRollbackRenderFrameId1, delayedInputFrameId, self.renderFrameId);
|
|
||||||
self.toRollbackRenderFrameId1 = null;
|
|
||||||
self.toRollbackRenderFrameId2 = null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const delayedInputFrameDownsync = self.assembleInputFrameDownsync(delayedInputFrameId);
|
let t0 = performance.now();
|
||||||
if (null == delayedInputFrameDownsync) {
|
if (self.shouldSendInputFrameUpsyncBatch(prevSelfInput, currSelfInput, self.lastUpsyncInputFrameId, noDelayInputFrameId)) {
|
||||||
console.warn("update(dt): recentInputCache is NOT having inputFrameId=", delayedInputFrameId, "; recentInputCache=", self._stringifyRecentInputCache(false));
|
// TODO: Is the following statement run asynchronously in an implicit manner? Should I explicitly run it asynchronously?
|
||||||
} else {
|
self.sendInputFrameUpsyncBatch(noDelayInputFrameId);
|
||||||
self._applyInputFrameDownsyncDynamics(delayedInputFrameDownsync, false);
|
}
|
||||||
}
|
|
||||||
const rdf = self._createRoomDownsyncFrameLocally();
|
let t1 = performance.now();
|
||||||
self._dumpToFullFrameCache(rdf);
|
// Use "fractional-frame-chasing" to guarantee that "self.update(dt)" is not jammed by a "large range of frame-chasing". See `<proj-root>/ConcerningEdgeCases.md` for the motivation.
|
||||||
/*
|
const prevChaserRenderFrameId = self.chaserRenderFrameId;
|
||||||
if (null != delayedInputFrameDownsync && null != delayedInputFrameDownsync.inputList && 0 < delayedInputFrameDownsync.inputList[self.selfPlayerInfo.joinIndex-1]) {
|
let nextChaserRenderFrameId = (prevChaserRenderFrameId + self.maxChasingRenderFramesPerUpdate);
|
||||||
console.log("My critical status: renderFrame=", JSON.stringify(rdf), ", delayedInputFrameDownsync=", JSON.stringify(delayedInputFrameDownsync));
|
if (nextChaserRenderFrameId > self.renderFrameId) nextChaserRenderFrameId = self.renderFrameId;
|
||||||
|
self.rollbackAndChase(prevChaserRenderFrameId, nextChaserRenderFrameId, self.chaserCollisionSys, self.chaserCollisionSysMap);
|
||||||
|
self.chaserRenderFrameId = nextChaserRenderFrameId; // Move the cursor "self.chaserRenderFrameId", keep in mind that "self.chaserRenderFrameId" is not monotonic!
|
||||||
|
let t2 = performance.now();
|
||||||
|
|
||||||
|
// Inside "self.rollbackAndChase", the "self.latestCollisionSys" is ALWAYS ROLLED BACK to "self.recentRenderCache.get(self.renderFrameId)" before being applied dynamics from corresponding inputFrameDownsync, REGARDLESS OF whether or not "self.chaserRenderFrameId == self.renderFrameId" now.
|
||||||
|
const rdf = self.rollbackAndChase(self.renderFrameId, self.renderFrameId+1, self.latestCollisionSys, self.latestCollisionSysMap);
|
||||||
|
|
||||||
|
self.applyRoomDownsyncFrameDynamics(rdf);
|
||||||
|
let t3 = performance.now();
|
||||||
|
/*
|
||||||
|
if (prevChaserRenderFrameId < nextChaserRenderFrameId) {
|
||||||
|
console.log("Took ", t1-t0, " milliseconds to send upsync cmds, ", t2-t1, " milliseconds to chase renderFrameIds=[", prevChaserRenderFrameId, ", ", nextChaserRenderFrameId, "], @renderFrameId=", self.renderFrameId);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error during Map.update", err);
|
||||||
|
} finally {
|
||||||
|
// Update countdown
|
||||||
|
if (null != self.countdownNanos) {
|
||||||
|
self.countdownNanos -= self.rollbackEstimatedDt*1000000000;
|
||||||
|
if (self.countdownNanos <= 0) {
|
||||||
|
self.onBattleStopped(self.playerRichInfoDict);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const countdownSeconds = parseInt(self.countdownNanos / 1000000000);
|
||||||
|
if (isNaN(countdownSeconds)) {
|
||||||
|
console.warn(`countdownSeconds is NaN for countdownNanos == ${self.countdownNanos}.`);
|
||||||
|
}
|
||||||
|
self.countdownLabel.string = countdownSeconds;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
++self.renderFrameId; // [WARNING] It's important to increment the renderFrameId AFTER all the operations above!!!
|
++self.renderFrameId; // [WARNING] It's important to increment the renderFrameId AFTER all the operations above!!!
|
||||||
}
|
}
|
||||||
const mapNode = self.node;
|
|
||||||
const canvasNode = mapNode.parent;
|
|
||||||
const canvasParentNode = canvasNode.parent;
|
|
||||||
if (null != window.boundRoomId) {
|
|
||||||
self.boundRoomIdLabel.string = window.boundRoomId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update countdown
|
|
||||||
if (null != self.countdownNanos) {
|
|
||||||
self.countdownNanos -= self.rollbackEstimatedDt*1000000000;
|
|
||||||
if (self.countdownNanos <= 0) {
|
|
||||||
self.onBattleStopped(self.playerRichInfoDict);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const countdownSeconds = parseInt(self.countdownNanos / 1000000000);
|
|
||||||
if (isNaN(countdownSeconds)) {
|
|
||||||
console.warn(`countdownSeconds is NaN for countdownNanos == ${self.countdownNanos}.`);
|
|
||||||
}
|
|
||||||
self.countdownLabel.string = countdownSeconds;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Error during Map.update", err);
|
|
||||||
}
|
|
||||||
if (null != self.ctrl) {
|
|
||||||
self.ctrl.justifyMapNodePosAndScale(self.ctrl.linearSpeedBase, self.ctrl.zoomingSpeedBase);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -904,54 +909,84 @@ cc.Class({
|
|||||||
setLocalZOrder(toShowNode, 10);
|
setLocalZOrder(toShowNode, 10);
|
||||||
},
|
},
|
||||||
|
|
||||||
playersMatched(playerMetas) {
|
onBattleReadyToStart(playerMetas, isSelfRejoining) {
|
||||||
console.log("Calling `playersMatched` with:", playerMetas);
|
console.log("Calling `onBattleReadyToStart` with:", playerMetas);
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
||||||
|
findingPlayerScriptIns.hideExitButton();
|
||||||
findingPlayerScriptIns.updatePlayersInfo(playerMetas);
|
findingPlayerScriptIns.updatePlayersInfo(playerMetas);
|
||||||
window.setTimeout(() => {
|
|
||||||
if (null != self.findingPlayerNode.parent) {
|
const hideFindingPlayersGUI = function() {
|
||||||
self.findingPlayerNode.parent.removeChild(self.findingPlayerNode);
|
if (null == self.findingPlayerNode.parent) return;
|
||||||
self.transitToState(ALL_MAP_STATES.VISUAL);
|
self.findingPlayerNode.parent.removeChild(self.findingPlayerNode);
|
||||||
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
|
};
|
||||||
for (let i in playerMetas) {
|
|
||||||
const playerMeta = playerMetas[i];
|
if (true == isSelfRejoining) {
|
||||||
playersInfoScriptIns.updateData(playerMeta);
|
hideFindingPlayersGUI();
|
||||||
}
|
} else {
|
||||||
}
|
// Delay to hide the "finding player" GUI, then show a countdown clock
|
||||||
const countDownScriptIns = self.countdownToBeginGameNode.getComponent("CountdownToBeginGame");
|
window.setTimeout(() => {
|
||||||
countDownScriptIns.setData();
|
hideFindingPlayersGUI();
|
||||||
self.showPopupInCanvas(self.countdownToBeginGameNode);
|
const countDownScriptIns = self.countdownToBeginGameNode.getComponent("CountdownToBeginGame");
|
||||||
return;
|
countDownScriptIns.setData();
|
||||||
}, 2000);
|
self.showPopupInCanvas(self.countdownToBeginGameNode);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_createRoomDownsyncFrameLocally() {
|
_createRoomDownsyncFrameLocally(renderFrameId, collisionSys, collisionSysMap) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
const prevRenderFrameId = renderFrameId-1;
|
||||||
|
const inputFrameForPrevRenderFrame = (
|
||||||
|
0 > prevRenderFrameId
|
||||||
|
?
|
||||||
|
null
|
||||||
|
:
|
||||||
|
self.getCachedInputFrameDownsyncWithPrediction(self._convertToInputFrameId(prevRenderFrameId, self.inputDelayFrames))
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Find a better way to assign speeds instead of using "speedRefRenderFrameId".
|
||||||
|
const speedRefRenderFrameId = prevRenderFrameId;
|
||||||
|
const speedRefRenderFrame = (
|
||||||
|
0 > prevRenderFrameId
|
||||||
|
?
|
||||||
|
null
|
||||||
|
:
|
||||||
|
self.recentRenderCache.getByFrameId(prevRenderFrameId)
|
||||||
|
);
|
||||||
|
|
||||||
const rdf = {
|
const rdf = {
|
||||||
id: self.renderFrameId,
|
id: renderFrameId,
|
||||||
refFrameId: self.renderFrameId,
|
refFrameId: renderFrameId,
|
||||||
players: {},
|
players: {}
|
||||||
countdownNanos: self.countdownNanos
|
|
||||||
};
|
};
|
||||||
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
||||||
const joinIndex = playerRichInfo.joinIndex;
|
const joinIndex = playerRichInfo.joinIndex;
|
||||||
const playerNode = playerRichInfo.node;
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
const playerScriptIns = playerRichInfo.scriptIns;
|
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||||
rdf.players[playerRichInfo.id] = {
|
rdf.players[playerRichInfo.id] = {
|
||||||
id: playerRichInfo.id,
|
id: playerRichInfo.id,
|
||||||
x: playerNode.position.x,
|
x: playerCollider.x,
|
||||||
y: playerNode.position.y,
|
y: playerCollider.y,
|
||||||
dir: playerScriptIns.activeDirection,
|
dir: self.ctrl.decodeDirection(null == inputFrameForPrevRenderFrame ? 0 : inputFrameForPrevRenderFrame.inputList[joinIndex-1]),
|
||||||
speed: playerScriptIns.speed,
|
speed: (null == speedRefRenderFrame ? playerRichInfo.speed : speedRefRenderFrame.players[playerRichInfo.id].speed),
|
||||||
joinIndex: joinIndex
|
joinIndex: joinIndex
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
if (
|
||||||
|
null != inputFrameForPrevRenderFrame && self._allConfirmed(inputFrameForPrevRenderFrame.confirmedList)
|
||||||
|
&&
|
||||||
|
self.lastAllConfirmedRenderFrameId >= prevRenderFrameId
|
||||||
|
&&
|
||||||
|
rdf.id > self.lastAllConfirmedRenderFrameId
|
||||||
|
) {
|
||||||
|
self.lastAllConfirmedRenderFrameId = rdf.id;
|
||||||
|
}
|
||||||
|
self._dumpToRenderCache(rdf);
|
||||||
return rdf;
|
return rdf;
|
||||||
},
|
},
|
||||||
|
|
||||||
_applyRoomDownsyncFrameDynamics(rdf) {
|
applyRoomDownsyncFrameDynamics(rdf) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
||||||
@ -962,11 +997,11 @@ cc.Class({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
assembleInputFrameDownsync(inputFrameId) {
|
getCachedInputFrameDownsyncWithPrediction(inputFrameId) {
|
||||||
const self = this;
|
const self = this;
|
||||||
let inputFrameDownsync = self.recentInputCache.get(inputFrameId);
|
let inputFrameDownsync = self.recentInputCache.getByFrameId(inputFrameId);
|
||||||
if (-1 != self.lastAllConfirmedInputFrameId && inputFrameId > self.lastAllConfirmedInputFrameId) {
|
if (null != inputFrameDownsync && -1 != self.lastAllConfirmedInputFrameId && inputFrameId > self.lastAllConfirmedInputFrameId) {
|
||||||
const lastAllConfirmedInputFrame = self.recentInputCache.get(self.lastAllConfirmedInputFrameId);
|
const lastAllConfirmedInputFrame = self.recentInputCache.getByFrameId(self.lastAllConfirmedInputFrameId);
|
||||||
for (let i = 0; i < inputFrameDownsync.inputList.length; ++i) {
|
for (let i = 0; i < inputFrameDownsync.inputList.length; ++i) {
|
||||||
if (i == self.selfPlayerInfo.joinIndex-1) continue;
|
if (i == self.selfPlayerInfo.joinIndex-1) continue;
|
||||||
inputFrameDownsync.inputList[i] = lastAllConfirmedInputFrame.inputList[i];
|
inputFrameDownsync.inputList[i] = lastAllConfirmedInputFrame.inputList[i];
|
||||||
@ -976,49 +1011,74 @@ cc.Class({
|
|||||||
return inputFrameDownsync;
|
return inputFrameDownsync;
|
||||||
},
|
},
|
||||||
|
|
||||||
_applyInputFrameDownsyncDynamics(inputFrameDownsync, invokeUpdateToo) {
|
rollbackAndChase(renderFrameIdSt, renderFrameIdEd, collisionSys, collisionSysMap) {
|
||||||
// This application DOESN'T use a "full physics engine", but only "collider detection" of "box2d", thus when resetting room state, there's no need of resetting "momentums".
|
if (renderFrameSt >= renderFrameIdEd) {
|
||||||
const self = this;
|
|
||||||
const inputs = inputFrameDownsync.inputList;
|
|
||||||
// Update controlled player nodes
|
|
||||||
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
|
||||||
const joinIndex = playerRichInfo.joinIndex;
|
|
||||||
const playerScriptIns = playerRichInfo.scriptIns;
|
|
||||||
const decodedInput = self.ctrl.decodeDirection(inputs[joinIndex-1]);
|
|
||||||
playerScriptIns.scheduleNewDirection(decodedInput, true);
|
|
||||||
if (invokeUpdateToo) {
|
|
||||||
playerScriptIns.update(self.rollbackEstimatedDt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (invokeUpdateToo) {
|
|
||||||
// [WARNING] CocosCreator v2.2.1 uses a singleton "CCDirector" to schedule "tree descendent updates" and "collision detections" in different timers, thus the following manual trigger of collision detection might not produce the same outcome for the "selfPlayer" as the other peers. Moreover, the aforementioned use of different timers is an intrinsic source of error!
|
|
||||||
|
|
||||||
cc.director._collisionManager.update(self.rollbackEstimatedDt); // Just to avoid unexpected wall penetration, no guarantee on determinism
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_rollbackAndReplay(inputFrameId1, renderFrameId1, inputFrameId2, renderFrameId2) {
|
|
||||||
const self = this;
|
|
||||||
const rdf1 = self.recentFrameCache.get(renderFrameId1);
|
|
||||||
if (null == rdf1) {
|
|
||||||
console.error("renderFrameId1=", renderFrameId1, "doesn't exist in recentFrameCache ", self._stringifyRecentFrameCache(false), ": COULDN'T ROLLBACK!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let t0 = performance.now();
|
const self = this;
|
||||||
self._applyRoomDownsyncFrameDynamics(rdf1);
|
const renderFrameSt = self.recentRenderCache.getByFrameId(renderFrameIdSt); // typed "RoomDownsyncFrame"
|
||||||
// DON'T apply inputFrameDownsync dynamics for exactly "renderFrameId2", see the comment around the invocation of "_rollbackAndReplay".
|
if (null == renderFrameSt) {
|
||||||
for (let renderFrameId = renderFrameId1; renderFrameId < renderFrameId2; ++renderFrameId) {
|
console.error("Couldn't find renderFrameId=", renderFrameIdSt, " to rollback, recentRenderCache=", self._stringifyRecentRenderCache(false));
|
||||||
const delayedInputFrameId = self._convertToInputFrameId(renderFrameId, self.inputDelayFrames);
|
}
|
||||||
const delayedInputFrameDownsync = self.assembleInputFrameDownsync(delayedInputFrameId);
|
/*
|
||||||
self._applyInputFrameDownsyncDynamics(delayedInputFrameDownsync, true);
|
Reset "position" of players in "collisionSys" according to "renderFrameSt". The easy part is that we don't have path-dependent-integrals to worry about like that of thermal dynamics.
|
||||||
// console.log("_rollbackAndReplay, AFTER:", self._stringifyRollbackResult(renderFrameId, delayedInputFrameDownsync));
|
*/
|
||||||
}
|
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
||||||
let t1 = performance.now();
|
const joinIndex = playerRichInfo.joinIndex;
|
||||||
console.log("Executed rollback-and-replay: [inputFrameId1:", inputFrameId1, ", inputFrameId2:", inputFrameId2, "), [renderFrameId1:", renderFrameId1, ", renderFrameId2:", renderFrameId2, "). It took", t1-t0, "milliseconds");
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
},
|
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||||
|
const player = renderFrameSt.players[playerId];
|
||||||
|
playerCollider.x = player.x;
|
||||||
|
playerCollider.y = player.y;
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function eventually calculates a "RoomDownsyncFrame" where "RoomDownsyncFrame.id == renderFrameIdEd".
|
||||||
|
*/
|
||||||
|
for (let i = renderFrameIdSt; i < renderFrameIdEd; ++i) {
|
||||||
|
const renderFrame = self.recentRenderCache.getByFrameId(i); // typed "RoomDownsyncFrame"
|
||||||
|
const j = self._convertToInputFrameId(i, self.inputDelayFrames);
|
||||||
|
const inputList = self.getCachedInputFrameDownsyncWithPrediction(j).inputList;
|
||||||
|
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
||||||
|
const joinIndex = playerRichInfo.joinIndex;
|
||||||
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
|
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||||
|
const player = renderFrame.players[playerId];
|
||||||
|
const encodedInput = inputList[joinIndex-1];
|
||||||
|
const decodedInput = self.ctrl.decodeDirection(encodedInput);
|
||||||
|
const baseChange = player.speed*self.rollbackEstimatedDt*decodedInput.speedFactor;
|
||||||
|
playerCollider.x += baseChange*decodedInput.dx;
|
||||||
|
playerCollider.y += baseChange*decodedInput.dy;
|
||||||
|
/*
|
||||||
|
if (0 < encodedInput) {
|
||||||
|
console.log("playerId=", playerId, "@renderFrameId=", i, ", delayedInputFrameId=", j, ", baseChange=", baseChange, ": x=", playerCollider.x, ", y=", playerCollider.y);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
|
||||||
|
collisionSys.update();
|
||||||
|
const result = collisionSys.createResult(); // Can I reuse a "self.latestCollisionSysResult" object throughout the whole battle?
|
||||||
|
|
||||||
|
// [WARNING] Traverse in the order of joinIndices to guarantee determinism.
|
||||||
|
for (let i in self.playerRichInfoArr) {
|
||||||
|
const joinIndex = parseInt(i) + 1;
|
||||||
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
|
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||||
|
const potentials = playerCollider.potentials();
|
||||||
|
for (const barrier of potentials) {
|
||||||
|
// Test if the player collides with the wall
|
||||||
|
if (!playerCollider.collides(barrier, result)) continue;
|
||||||
|
// Push the player out of the wall
|
||||||
|
playerCollider.x -= result.overlap * result.overlap_x;
|
||||||
|
playerCollider.y -= result.overlap * result.overlap_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self._createRoomDownsyncFrameLocally(renderFrameIdEd, collisionSys, collisionSysMap);
|
||||||
|
},
|
||||||
|
|
||||||
_initPlayerRichInfoDict(players, playerMetas) {
|
_initPlayerRichInfoDict(players, playerMetas) {
|
||||||
const self = this;
|
const self = this;
|
||||||
for (let k in players) {
|
for (let k in players) {
|
||||||
@ -1039,61 +1099,36 @@ cc.Class({
|
|||||||
nodeAndScriptIns[1].showArrowTipNode();
|
nodeAndScriptIns[1].showArrowTipNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
self.playerRichInfoArr = new Array(self.playerRichInfoDict.size);
|
||||||
|
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
||||||
_stringifyRecentFrameCache(usefullOutput) {
|
self.playerRichInfoArr[playerRichInfo.joinIndex-1] = playerRichInfo;
|
||||||
if (true == usefullOutput) {
|
});
|
||||||
let s = [];
|
|
||||||
self.recentFrameCache.forEach((roomDownsyncFrame, renderFrameId) => {
|
|
||||||
s.push(JSON.stringify(roomDownsyncFrame));
|
|
||||||
});
|
|
||||||
|
|
||||||
return s.join('\n');
|
|
||||||
}
|
|
||||||
return "[stRenderFrameId=" + self.recentFrameCacheSt + ", edRenderFrameId=" + self.recentFrameCacheEd + ")";
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_stringifyRecentInputCache(usefullOutput) {
|
_stringifyRecentInputCache(usefullOutput) {
|
||||||
|
const self = this;
|
||||||
if (true == usefullOutput) {
|
if (true == usefullOutput) {
|
||||||
let s = [];
|
let s = [];
|
||||||
self.recentInputCache.forEach((inputFrameDownsync, inputFrameId) => {
|
for (let i = self.recentInputCache.stFrameId; i < self.recentInputCache.edFrameId; ++i) {
|
||||||
s.push(JSON.stringify(inputFrameDownsync));
|
s.push(JSON.stringify(self.recentInputCache.getByFrameId(i)));
|
||||||
});
|
}
|
||||||
|
|
||||||
return s.join('\n');
|
return s.join('\n');
|
||||||
}
|
}
|
||||||
return "[stInputFrameId=" + self.recentInputCacheSt + ", edInputFrameId=" + self.recentInputCacheEd + ")";
|
return "[stInputFrameId=" + self.recentInputCache.stFrameId + ", edInputFrameId=" + self.recentInputCache.edFrameId + ")";
|
||||||
},
|
},
|
||||||
|
|
||||||
_stringifyRollbackResult(renderFrameId, delayedInputFrameDownsync) {
|
_stringifyRecentRenderCache(usefullOutput) {
|
||||||
// Slightly different from "_createRoomDownsyncFrameLocally"
|
|
||||||
const self = this;
|
const self = this;
|
||||||
const s = (
|
if (true == usefullOutput) {
|
||||||
null == delayedInputFrameDownsync
|
let s = [];
|
||||||
?
|
for (let i = self.recentRenderCache.stFrameId; i < self.recentRenderCache.edFrameId; ++i) {
|
||||||
{
|
s.push(JSON.stringify(self.recentRenderCache.getByFrameId(i)));
|
||||||
renderFrameId: renderFrameId,
|
|
||||||
players: {}
|
|
||||||
}
|
}
|
||||||
:
|
|
||||||
{
|
|
||||||
renderFrameId: renderFrameId,
|
|
||||||
players: {},
|
|
||||||
delayedInputFrameDownsync: delayedInputFrameDownsync,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
let players = {};
|
|
||||||
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
|
|
||||||
const joinIndex = playerRichInfo.joinIndex;
|
|
||||||
const playerNode = playerRichInfo.node;
|
|
||||||
const playerScriptIns = playerRichInfo.scriptIns;
|
|
||||||
s.players[playerRichInfo.id] = {
|
|
||||||
id: playerRichInfo.id,
|
|
||||||
x: playerNode.position.x,
|
|
||||||
y: playerNode.position.y,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return JSON.stringify(s);
|
return s.join('\n');
|
||||||
|
}
|
||||||
|
return "[stRenderFrameId=" + self.recentRenderCache.stFrameId + ", edRenderFrameId=" + self.recentRenderCache.edFrameId + ")";
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
63
frontend/assets/scripts/RingBuffer.js
Normal file
63
frontend/assets/scripts/RingBuffer.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
var RingBuffer = function(capacity) {
|
||||||
|
this.ed = 0; // write index, open index
|
||||||
|
this.st = 0; // read index, closed index
|
||||||
|
this.edFrameId = 0;
|
||||||
|
this.stFrameId = 0;
|
||||||
|
this.n = capacity;
|
||||||
|
this.cnt = 0; // the count of valid elements in the buffer, used mainly to distinguish what "st == ed" means for "Pop" and "Get" methods
|
||||||
|
this.eles = new Array(capacity).fill(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
RingBuffer.prototype.put = function(item) {
|
||||||
|
this.eles[this.ed] = item
|
||||||
|
this.edFrameId++;
|
||||||
|
this.cnt++;
|
||||||
|
this.ed++;
|
||||||
|
if (this.ed >= this.n) {
|
||||||
|
this.ed -= this.n; // Deliberately not using "%" operator for performance concern
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RingBuffer.prototype.pop = function() {
|
||||||
|
if (0 == this.cnt) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const item = this.eles[this.st];
|
||||||
|
this.stFrameId++;
|
||||||
|
this.cnt--;
|
||||||
|
this.st++;
|
||||||
|
if (this.st >= this.n) {
|
||||||
|
this.st -= this.n;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
RingBuffer.prototype.getByOffset = function(offsetFromSt) {
|
||||||
|
if (0 == this.cnt) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let arrIdx = this.st + offsetFromSt;
|
||||||
|
if (this.st < this.ed) {
|
||||||
|
// case#1: 0...st...ed...n-1
|
||||||
|
if (this.st <= arrIdx && arrIdx < this.ed) {
|
||||||
|
return this.eles[arrIdx];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if this.st >= this.sd
|
||||||
|
// case#2: 0...ed...st...n-1
|
||||||
|
if (arrIdx >= this.n) {
|
||||||
|
arrIdx -= this.n
|
||||||
|
}
|
||||||
|
if (arrIdx >= this.st || arrIdx < this.ed) {
|
||||||
|
return this.eles[arrIdx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
RingBuffer.prototype.getByFrameId = function(frameId) {
|
||||||
|
return this.getByOffset(frameId - this.stFrameId);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = RingBuffer;
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ver": "1.0.5",
|
"ver": "1.0.5",
|
||||||
"uuid": "8264fb72-e348-45e4-9ab3-5bffb9a561ee",
|
"uuid": "9ec706f0-811c-403b-93a7-b34a7e5f8068",
|
||||||
"isPlugin": false,
|
"isPlugin": false,
|
||||||
"loadPluginInWeb": true,
|
"loadPluginInWeb": true,
|
||||||
"loadPluginInNative": true,
|
"loadPluginInNative": true,
|
@ -334,10 +334,6 @@ window.battleEntityTypeNameToGlobalGid = {};
|
|||||||
TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNode) {
|
TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNode) {
|
||||||
let toRet = {
|
let toRet = {
|
||||||
barriers: [],
|
barriers: [],
|
||||||
shelters: [],
|
|
||||||
shelterChainTails: [],
|
|
||||||
shelterChainHeads: [],
|
|
||||||
sheltersZReducer: [],
|
|
||||||
frameAnimations: [],
|
frameAnimations: [],
|
||||||
grandBoundaries: [],
|
grandBoundaries: [],
|
||||||
};
|
};
|
||||||
@ -393,8 +389,6 @@ TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNo
|
|||||||
let childrenOfCurrentTile = null;
|
let childrenOfCurrentTile = null;
|
||||||
if (cc.sys.isNative) {
|
if (cc.sys.isNative) {
|
||||||
childrenOfCurrentTile = currentTile.getElementsByTagName("objectgroup");
|
childrenOfCurrentTile = currentTile.getElementsByTagName("objectgroup");
|
||||||
} else if (cc.sys.platform == cc.sys.WECHAT_GAME) {
|
|
||||||
childrenOfCurrentTile = currentTile.childNodes;
|
|
||||||
} else {
|
} else {
|
||||||
childrenOfCurrentTile = currentTile.children;
|
childrenOfCurrentTile = currentTile.children;
|
||||||
}
|
}
|
||||||
@ -404,8 +398,6 @@ TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNo
|
|||||||
var currentObjectGroupUnderTile = mapInfo._parseObjectGroup(ch);
|
var currentObjectGroupUnderTile = mapInfo._parseObjectGroup(ch);
|
||||||
gidBoundariesMap[parentGid] = {
|
gidBoundariesMap[parentGid] = {
|
||||||
barriers: [],
|
barriers: [],
|
||||||
shelters: [],
|
|
||||||
sheltersZReducer: [],
|
|
||||||
};
|
};
|
||||||
for (let oidx = 0; oidx < currentObjectGroupUnderTile._objects.length; ++oidx) {
|
for (let oidx = 0; oidx < currentObjectGroupUnderTile._objects.length; ++oidx) {
|
||||||
const oo = currentObjectGroupUnderTile._objects[oidx];
|
const oo = currentObjectGroupUnderTile._objects[oidx];
|
||||||
@ -429,22 +421,6 @@ TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNo
|
|||||||
brToPushTmp.boundaryType = boundaryType;
|
brToPushTmp.boundaryType = boundaryType;
|
||||||
gidBoundariesMap[parentGid].barriers.push(brToPushTmp);
|
gidBoundariesMap[parentGid].barriers.push(brToPushTmp);
|
||||||
break;
|
break;
|
||||||
case "shelter":
|
|
||||||
let shToPushTmp = [];
|
|
||||||
for (let shidx = 0; shidx < polylinePoints.length; ++shidx) {
|
|
||||||
shToPushTmp.push(cc.v2(oo.x, oo.y).add(polylinePoints[shidx]));
|
|
||||||
}
|
|
||||||
shToPushTmp.boundaryType = boundaryType;
|
|
||||||
gidBoundariesMap[parentGid].shelters.push(shToPushTmp);
|
|
||||||
break;
|
|
||||||
case "shelter_z_reducer":
|
|
||||||
let shzrToPushTmp = [];
|
|
||||||
for (let shzridx = 0; shzridx < polylinePoints.length; ++shzridx) {
|
|
||||||
shzrToPushTmp.push(cc.v2(oo.x, oo.y).add(polylinePoints[shzridx]));
|
|
||||||
}
|
|
||||||
shzrToPushTmp.boundaryType = boundaryType;
|
|
||||||
gidBoundariesMap[parentGid].sheltersZReducer.push(shzrToPushTmp);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -510,22 +486,6 @@ TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNo
|
|||||||
toPushBarriers.boundaryType = boundaryType;
|
toPushBarriers.boundaryType = boundaryType;
|
||||||
toRet.barriers.push(toPushBarriers);
|
toRet.barriers.push(toPushBarriers);
|
||||||
break;
|
break;
|
||||||
case "shelter":
|
|
||||||
let toPushShelters = [];
|
|
||||||
for (let kk = 0; kk < polylinePoints.length; ++kk) {
|
|
||||||
toPushShelters.push(this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, object.offset.add(polylinePoints[kk])));
|
|
||||||
}
|
|
||||||
toPushShelters.boundaryType = boundaryType;
|
|
||||||
toRet.shelters.push(toPushShelters);
|
|
||||||
break;
|
|
||||||
case "shelter_z_reducer":
|
|
||||||
let toPushSheltersZReducer = [];
|
|
||||||
for (let kkk = 0; kkk < polylinePoints.length; ++kkk) {
|
|
||||||
toPushSheltersZReducer.push(this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, object.offset.add(polylinePoints[kkk])));
|
|
||||||
}
|
|
||||||
toPushSheltersZReducer.boundaryType = boundaryType;
|
|
||||||
toRet.sheltersZReducer.push(toPushSheltersZReducer);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -536,7 +496,7 @@ TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNo
|
|||||||
|
|
||||||
let layerDOMTrees = [];
|
let layerDOMTrees = [];
|
||||||
const mapDomTree = mapInfo._parser._parseXML(tiledMapIns.tmxAsset.tmxXmlStr).documentElement;
|
const mapDomTree = mapInfo._parser._parseXML(tiledMapIns.tmxAsset.tmxXmlStr).documentElement;
|
||||||
const mapDOMAllChildren = (cc.sys.platform == cc.sys.WECHAT_GAME ? mapDomTree.childNodes : mapDomTree.children);
|
const mapDOMAllChildren = (mapDomTree.children);
|
||||||
for (let mdtIdx = 0; mdtIdx < mapDOMAllChildren.length; ++mdtIdx) {
|
for (let mdtIdx = 0; mdtIdx < mapDOMAllChildren.length; ++mdtIdx) {
|
||||||
const tmpCh = mapDOMAllChildren[mdtIdx];
|
const tmpCh = mapDOMAllChildren[mdtIdx];
|
||||||
if (mapInfo._shouldIgnoreNode(tmpCh)) {
|
if (mapInfo._shouldIgnoreNode(tmpCh)) {
|
||||||
@ -585,23 +545,6 @@ TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNo
|
|||||||
}
|
}
|
||||||
toRet.barriers.push(brToPushTmp);
|
toRet.barriers.push(brToPushTmp);
|
||||||
}
|
}
|
||||||
for (let shidx = 0; shidx < gidBoundaries.shelters.length; ++shzridx) {
|
|
||||||
const theShelter = gidBoundaries.shelters[shidx]; // An array of cc.v2 points.
|
|
||||||
let shToPushTmp = [];
|
|
||||||
for (let tshidx = 0; tshidx < theShelter.length; ++tshidx) {
|
|
||||||
shToPushTmp.push(topLeftOfWholeTsxTileInMapNode.add(cc.v2(theShelter[tshidx].x, -theShelter[tshidx].y)));
|
|
||||||
}
|
|
||||||
toRet.shelters.push(shToPushTmp);
|
|
||||||
}
|
|
||||||
for (let shzridx = 0; shzridx < gidBoundaries.sheltersZReducer.length; ++shzridx) {
|
|
||||||
const theShelter = gidBoundaries.sheltersZReducer[shzridx]; // An array of cc.v2 points.
|
|
||||||
let shzrToPushTmp = [];
|
|
||||||
for (let tshzridx = 0; tshzridx < theShelter.length; ++tshzridx) {
|
|
||||||
shzrToPushTmp.push(topLeftOfWholeTsxTileInMapNode.add(cc.v2(theShelter[tshzridx].x, -theShelter[tshzridx].y)));
|
|
||||||
}
|
|
||||||
toRet.sheltersZReducer.push(shzrToPushTmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -637,6 +580,7 @@ TileCollisionManager.prototype.isOutOfMapNode = function (tiledMapNode, continuo
|
|||||||
};
|
};
|
||||||
|
|
||||||
TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScriptIns, mapNode, extractedBoundaryObjs) {
|
TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScriptIns, mapNode, extractedBoundaryObjs) {
|
||||||
|
// TODO: TO DEPRECATE!
|
||||||
const tiledMapIns = mapNode.getComponent(cc.TiledMap);
|
const tiledMapIns = mapNode.getComponent(cc.TiledMap);
|
||||||
if (extractedBoundaryObjs.grandBoundaries) {
|
if (extractedBoundaryObjs.grandBoundaries) {
|
||||||
window.grandBoundary = [];
|
window.grandBoundary = [];
|
||||||
@ -683,47 +627,6 @@ TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScript
|
|||||||
frameAnimInType.push(animNode);
|
frameAnimInType.push(animNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let boundaryObj of extractedBoundaryObjs.shelterChainTails) {
|
|
||||||
const newShelter = cc.instantiate(mapScriptIns.polygonBoundaryShelterPrefab);
|
|
||||||
const newBoundaryOffsetInMapNode = cc.v2(boundaryObj[0].x, boundaryObj[0].y);
|
|
||||||
newShelter.setPosition(newBoundaryOffsetInMapNode);
|
|
||||||
newShelter.setAnchorPoint(cc.v2(0, 0));
|
|
||||||
const newShelterColliderIns = newShelter.getComponent(cc.PolygonCollider);
|
|
||||||
newShelterColliderIns.points = [];
|
|
||||||
for (let p of boundaryObj) {
|
|
||||||
newShelterColliderIns.points.push(p.sub(newBoundaryOffsetInMapNode));
|
|
||||||
}
|
|
||||||
newShelter.pTiledLayer = boundaryObj.pTiledLayer;
|
|
||||||
newShelter.tileDiscretePos = boundaryObj.tileDiscretePos;
|
|
||||||
if (null != boundaryObj.imageObject) {
|
|
||||||
newShelter.imageObject = boundaryObj.imageObject;
|
|
||||||
newShelter.tailOrHead = "tail";
|
|
||||||
window.addToGlobalShelterChainVerticeMap(newShelter.imageObject.imageObjectNode); // Deliberately NOT adding at the "traversal of shelterChainHeads".
|
|
||||||
}
|
|
||||||
newShelter.boundaryObj = boundaryObj;
|
|
||||||
mapScriptIns.node.addChild(newShelter);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let boundaryObj of extractedBoundaryObjs.shelterChainHeads) {
|
|
||||||
const newShelter = cc.instantiate(mapScriptIns.polygonBoundaryShelterPrefab);
|
|
||||||
const newBoundaryOffsetInMapNode = cc.v2(boundaryObj[0].x, boundaryObj[0].y);
|
|
||||||
newShelter.setPosition(newBoundaryOffsetInMapNode);
|
|
||||||
newShelter.setAnchorPoint(cc.v2(0, 0));
|
|
||||||
const newShelterColliderIns = newShelter.getComponent(cc.PolygonCollider);
|
|
||||||
newShelterColliderIns.points = [];
|
|
||||||
for (let p of boundaryObj) {
|
|
||||||
newShelterColliderIns.points.push(p.sub(newBoundaryOffsetInMapNode));
|
|
||||||
}
|
|
||||||
newShelter.pTiledLayer = boundaryObj.pTiledLayer;
|
|
||||||
newShelter.tileDiscretePos = boundaryObj.tileDiscretePos;
|
|
||||||
if (null != boundaryObj.imageObject) {
|
|
||||||
newShelter.imageObject = boundaryObj.imageObject;
|
|
||||||
newShelter.tailOrHead = "head";
|
|
||||||
}
|
|
||||||
newShelter.boundaryObj = boundaryObj;
|
|
||||||
mapScriptIns.node.addChild(newShelter);
|
|
||||||
}
|
|
||||||
|
|
||||||
mapScriptIns.barrierColliders = [];
|
mapScriptIns.barrierColliders = [];
|
||||||
for (let boundaryObj of extractedBoundaryObjs.barriers) {
|
for (let boundaryObj of extractedBoundaryObjs.barriers) {
|
||||||
const newBarrier = cc.instantiate(mapScriptIns.polygonBoundaryBarrierPrefab);
|
const newBarrier = cc.instantiate(mapScriptIns.polygonBoundaryBarrierPrefab);
|
||||||
@ -739,19 +642,6 @@ TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScript
|
|||||||
mapScriptIns.node.addChild(newBarrier);
|
mapScriptIns.node.addChild(newBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let boundaryObj of extractedBoundaryObjs.sheltersZReducer) {
|
|
||||||
const newShelter = cc.instantiate(mapScriptIns.polygonBoundaryShelterZReducerPrefab);
|
|
||||||
const newBoundaryOffsetInMapNode = cc.v2(boundaryObj[0].x, boundaryObj[0].y);
|
|
||||||
newShelter.setPosition(newBoundaryOffsetInMapNode);
|
|
||||||
newShelter.setAnchorPoint(cc.v2(0, 0));
|
|
||||||
const newShelterColliderIns = newShelter.getComponent(cc.PolygonCollider);
|
|
||||||
newShelterColliderIns.points = [];
|
|
||||||
for (let p of boundaryObj) {
|
|
||||||
newShelterColliderIns.points.push(p.sub(newBoundaryOffsetInMapNode));
|
|
||||||
}
|
|
||||||
mapScriptIns.node.addChild(newShelter);
|
|
||||||
}
|
|
||||||
|
|
||||||
const allLayers = tiledMapIns.getLayers();
|
const allLayers = tiledMapIns.getLayers();
|
||||||
for (let layer of allLayers) {
|
for (let layer of allLayers) {
|
||||||
const layerType = layer.getProperty("type");
|
const layerType = layer.getProperty("type");
|
||||||
@ -759,10 +649,6 @@ TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScript
|
|||||||
case "barrier_and_shelter":
|
case "barrier_and_shelter":
|
||||||
setLocalZOrder(layer.node, 3);
|
setLocalZOrder(layer.node, 3);
|
||||||
break;
|
break;
|
||||||
case "shelter_preview":
|
|
||||||
layer.node.opacity = 100;
|
|
||||||
setLocalZOrder(layer.node, 500);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
window.DIRECTION_DECODER = [
|
window.DIRECTION_DECODER = [
|
||||||
[0, 0],
|
[0, 0, null],
|
||||||
[0, +1],
|
[0, +1, null],
|
||||||
[0, -1],
|
[0, -1, null],
|
||||||
[+2, 0],
|
[+2, 0, null],
|
||||||
[-2, 0],
|
[-2, 0, null],
|
||||||
[+2, +1],
|
[+2, +1, null],
|
||||||
[-2, -1],
|
[-2, -1, null],
|
||||||
[+2, -1],
|
[+2, -1, null],
|
||||||
[-2, +1],
|
[-2, +1, null],
|
||||||
[+2, 0],
|
[+2, 0, null],
|
||||||
[-2, 0],
|
[-2, 0, null],
|
||||||
[0, +1],
|
[0, +1, null],
|
||||||
[0, -1],
|
[0, -1, null],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
for (let k in window.DIRECTION_DECODER) {
|
||||||
|
const length = Math.sqrt(window.DIRECTION_DECODER[k][0]*window.DIRECTION_DECODER[k][0] + window.DIRECTION_DECODER[k][1]*window.DIRECTION_DECODER[k][1]);
|
||||||
|
window.DIRECTION_DECODER[k][2] = (0 == length ? 0 : (1.0/length));
|
||||||
|
}
|
||||||
|
|
||||||
cc.Class({
|
cc.Class({
|
||||||
extends: cc.Component,
|
extends: cc.Component,
|
||||||
properties: {
|
properties: {
|
||||||
@ -114,43 +119,6 @@ cc.Class({
|
|||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
justifyMapNodePosAndScale(linearSpeedBase, zoomingSpeedBase) {
|
|
||||||
const self = this;
|
|
||||||
if (false == self.mapScriptIns._inputControlEnabled) return;
|
|
||||||
if (null != self._cachedMapNodePosTarget) {
|
|
||||||
while (self.maxMovingBufferLength < self._cachedMapNodePosTarget.length) {
|
|
||||||
self._cachedMapNodePosTarget.shift();
|
|
||||||
}
|
|
||||||
if (0 < self._cachedMapNodePosTarget.length && 0 == self.mapNode.getNumberOfRunningActions()) {
|
|
||||||
const nextMapNodePosTarget = self._cachedMapNodePosTarget.shift();
|
|
||||||
const linearSpeed = linearSpeedBase;
|
|
||||||
const finalDiffVec = nextMapNodePosTarget.pos.sub(self.mapNode.position);
|
|
||||||
const finalDiffVecMag = finalDiffVec.mag();
|
|
||||||
if (self.linearMovingEps > finalDiffVecMag) {
|
|
||||||
// Jittering.
|
|
||||||
// cc.log("Map node moving by finalDiffVecMag == %s is just jittering.", finalDiffVecMag);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const durationSeconds = finalDiffVecMag / linearSpeed;
|
|
||||||
cc.log("Map node moving to %o in %s/%s == %s seconds.", nextMapNodePosTarget.pos, finalDiffVecMag, linearSpeed, durationSeconds);
|
|
||||||
const bufferedTargetPos = cc.v2(nextMapNodePosTarget.pos.x, nextMapNodePosTarget.pos.y);
|
|
||||||
self.mapNode.runAction(cc.sequence(
|
|
||||||
cc.moveTo(durationSeconds, bufferedTargetPos),
|
|
||||||
cc.callFunc(() => {
|
|
||||||
if (self._isMapOverMoved(self.mapNode.position)) {
|
|
||||||
self.mapNode.setPosition(bufferedTargetPos);
|
|
||||||
}
|
|
||||||
}, self)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (null != self._cachedZoomRawTarget && false == self._cachedZoomRawTarget.processed) {
|
|
||||||
cc.log(`Processing self._cachedZoomRawTarget == ${self._cachedZoomRawTarget}`);
|
|
||||||
self._cachedZoomRawTarget.processed = true;
|
|
||||||
self.mapNode.setScale(self._cachedZoomRawTarget.scale);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_initTouchEvent() {
|
_initTouchEvent() {
|
||||||
const self = this;
|
const self = this;
|
||||||
const translationListenerNode = (self.translationListenerNode ? self.translationListenerNode : self.mapNode);
|
const translationListenerNode = (self.translationListenerNode ? self.translationListenerNode : self.mapNode);
|
||||||
@ -377,7 +345,8 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
dx: mapped[0],
|
dx: mapped[0],
|
||||||
dy: mapped[1]
|
dy: mapped[1],
|
||||||
|
speedFactor: mapped[2],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,628 +0,0 @@
|
|||||||
const i18n = require('LanguageData');
|
|
||||||
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
|
|
||||||
|
|
||||||
const WECHAT_ON_HIDE_TARGET_ACTION = {
|
|
||||||
SHARE_CHAT_MESSAGE: 8,
|
|
||||||
CLOSE: 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
const pbStructRoot = require('./modules/room_downsync_frame_proto_bundle.forcemsg.js');
|
|
||||||
window.RoomDownsyncFrame = pbStructRoot.treasurehunterx.RoomDownsyncFrame;
|
|
||||||
window.BattleColliderInfo = pbStructRoot.treasurehunterx.BattleColliderInfo;
|
|
||||||
|
|
||||||
cc.Class({
|
|
||||||
extends: cc.Component,
|
|
||||||
|
|
||||||
properties: {
|
|
||||||
cavasNode: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Node
|
|
||||||
},
|
|
||||||
backgroundNode: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Node
|
|
||||||
},
|
|
||||||
loadingPrefab: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Prefab
|
|
||||||
},
|
|
||||||
tipsLabel: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Label,
|
|
||||||
},
|
|
||||||
|
|
||||||
downloadProgress: {
|
|
||||||
default: null,
|
|
||||||
type: cc.ProgressBar,
|
|
||||||
},
|
|
||||||
writtenBytes: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Label,
|
|
||||||
},
|
|
||||||
expectedToWriteBytes: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Label,
|
|
||||||
},
|
|
||||||
|
|
||||||
handlerProgress: {
|
|
||||||
default: null,
|
|
||||||
type: cc.ProgressBar,
|
|
||||||
},
|
|
||||||
handledUrlsCount: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Label,
|
|
||||||
},
|
|
||||||
toHandledUrlsCount: {
|
|
||||||
default: null,
|
|
||||||
type: cc.Label,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// LIFE-CYCLE CALLBACKS:
|
|
||||||
onLoad() {
|
|
||||||
wx.onShow((res) => {
|
|
||||||
console.log("+++++ wx onShow(), onShow.res ", res);
|
|
||||||
window.expectedRoomId = res.query.expectedRoomId;
|
|
||||||
});
|
|
||||||
wx.onHide((res) => {
|
|
||||||
// Reference https://developers.weixin.qq.com/minigame/dev/api/wx.exitMiniProgram.html.
|
|
||||||
console.log("+++++ wx onHide(), onHide.res: ", res);
|
|
||||||
if (
|
|
||||||
WECHAT_ON_HIDE_TARGET_ACTION == res.targetAction
|
|
||||||
||
|
|
||||||
"back" == res.mode // After "WeChat v7.0.4 on iOS"
|
|
||||||
||
|
|
||||||
"close" == res.mode
|
|
||||||
) {
|
|
||||||
window.clearLocalStorageAndBackToLoginScene();
|
|
||||||
} else {
|
|
||||||
// Deliberately left blank.
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const self = this;
|
|
||||||
self.getRetCodeList();
|
|
||||||
self.getRegexList();
|
|
||||||
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_1"));
|
|
||||||
self.checkIntAuthTokenExpire().then(
|
|
||||||
() => {
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_2"));
|
|
||||||
const intAuthToken = JSON.parse(cc.sys.localStorage.getItem('selfPlayer')).intAuthToken;
|
|
||||||
self.useTokenLogin(intAuthToken);
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
// 调用wx.login然后请求登录。
|
|
||||||
wx.authorize({
|
|
||||||
scope: "scope.userInfo",
|
|
||||||
success() {
|
|
||||||
self.showTips(i18n.t("login.tips.WECHAT_AUTHORIZED_AND_INT_AUTH_TOKEN_LOGGING_IN"));
|
|
||||||
wx.login({
|
|
||||||
success(res) {
|
|
||||||
console.log("wx login success, res: ", res);
|
|
||||||
const code = res.code;
|
|
||||||
|
|
||||||
wx.getUserInfo({
|
|
||||||
success(res) {
|
|
||||||
const userInfo = res.userInfo;
|
|
||||||
console.log("Get user info ok: ", userInfo);
|
|
||||||
self.useWxCodeMiniGameLogin(code, userInfo);
|
|
||||||
},
|
|
||||||
fail(err) {
|
|
||||||
console.error(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"), err);
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"));
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail(err) {
|
|
||||||
if (err) {
|
|
||||||
console.error(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"), err);
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"));
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail(err) {
|
|
||||||
console.error(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"), err);
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"));
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
createAuthorizeThenLoginButton(tips) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
let sysInfo = wx.getSystemInfoSync();
|
|
||||||
//获取微信界面大小
|
|
||||||
let width = sysInfo.screenWidth;
|
|
||||||
let height = sysInfo.screenHeight;
|
|
||||||
|
|
||||||
let button = wx.createUserInfoButton({
|
|
||||||
type: 'text',
|
|
||||||
text: '',
|
|
||||||
style: {
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
backgroundColor: '#00000000', //最后两位为透明度
|
|
||||||
color: '#ffffff',
|
|
||||||
fontSize: 20,
|
|
||||||
textAlign: "center",
|
|
||||||
lineHeight: height,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
button.onTap((res) => {
|
|
||||||
console.log(res);
|
|
||||||
if (null != res.userInfo) {
|
|
||||||
const userInfo = res.userInfo;
|
|
||||||
self.showTips(i18n.t("login.tips.WECHAT_AUTHORIZED_AND_INT_AUTH_TOKEN_LOGGING_IN"));
|
|
||||||
|
|
||||||
wx.login({
|
|
||||||
success(res) {
|
|
||||||
console.log('wx.login success, res:', res);
|
|
||||||
const code = res.code;
|
|
||||||
self.useWxCodeMiniGameLogin(code, userInfo);
|
|
||||||
button.destroy();
|
|
||||||
},
|
|
||||||
fail(err) {
|
|
||||||
console.err(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"), err);
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
self.showTips(i18n.t("login.tips.PLEASE_AUTHORIZE_WECHAT_LOGIN_FIRST"));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
onDestroy() {
|
|
||||||
console.log("+++++++ WechatGameLogin onDestroy()");
|
|
||||||
},
|
|
||||||
|
|
||||||
showTips(text) {
|
|
||||||
if (this.tipsLabel != null) {
|
|
||||||
this.tipsLabel.string = text;
|
|
||||||
} else {
|
|
||||||
console.log('Login scene showTips failed')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getRetCodeList() {
|
|
||||||
const self = this;
|
|
||||||
self.retCodeDict = constants.RET_CODE;
|
|
||||||
},
|
|
||||||
|
|
||||||
getRegexList() {
|
|
||||||
const self = this;
|
|
||||||
self.regexList = {
|
|
||||||
EMAIL: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
|
||||||
PHONE: /^\+?[0-9]{8,14}$/,
|
|
||||||
STREET_META: /^.{5,100}$/,
|
|
||||||
LNG_LAT_TEXT: /^[0-9]+(\.[0-9]{4,6})$/,
|
|
||||||
SEO_KEYWORD: /^.{2,50}$/,
|
|
||||||
PASSWORD: /^.{6,50}$/,
|
|
||||||
SMS_CAPTCHA_CODE: /^[0-9]{4}$/,
|
|
||||||
ADMIN_HANDLE: /^.{4,50}$/,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
onSMSCaptchaGetButtonClicked(evt) {
|
|
||||||
var timerEnable = true;
|
|
||||||
const self = this;
|
|
||||||
if (!self.checkPhoneNumber('getCaptcha')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
url: backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER +
|
|
||||||
constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.SMS_CAPTCHA + constants.ROUTE_PATH.GET,
|
|
||||||
type: 'GET',
|
|
||||||
data: {
|
|
||||||
phoneCountryCode: self.phoneCountryCodeInput.getComponent(cc.EditBox).string,
|
|
||||||
phoneNum: self.phoneNumberInput.getComponent(cc.EditBox).string
|
|
||||||
},
|
|
||||||
success: function(res) {
|
|
||||||
switch (res.ret) {
|
|
||||||
case constants.RET_CODE.OK:
|
|
||||||
self.phoneNumberTips.getComponent(cc.Label).string = '';
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = '';
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.DUPLICATED:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.DUPLICATED");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.INCORRECT_PHONE_COUNTRY_CODE:
|
|
||||||
case constants.RET_CODE.INCORRECT_PHONE_NUMBER:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.PHONE_ERR");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.IS_TEST_ACC:
|
|
||||||
self.smsLoginCaptchaInput.getComponent(cc.EditBox).string = res.smsLoginCaptcha;
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.TEST_USER");
|
|
||||||
timerEnable = false;
|
|
||||||
// clearInterval(self.countdownTimer);
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.SMS_CAPTCHA_REQUESTED_TOO_FREQUENTLY:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.SMS_CAPTCHA_FREEQUENT_REQUIRE");
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (timerEnable)
|
|
||||||
self.countdownTime(self);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
countdownTime(self) {
|
|
||||||
self.smsLoginCaptchaButton.off('click', self.onSMSCaptchaGetButtonClicked);
|
|
||||||
self.smsLoginCaptchaButton.removeChild(self.smsGetCaptchaNode);
|
|
||||||
self.smsWaitCountdownNode.parent = self.smsLoginCaptchaButton;
|
|
||||||
var total = 20; // Magic number
|
|
||||||
self.countdownTimer = setInterval(function() {
|
|
||||||
if (total === 0) {
|
|
||||||
self.smsWaitCountdownNode.parent.removeChild(self.smsWaitCountdownNode);
|
|
||||||
self.smsGetCaptchaNode.parent = self.smsLoginCaptchaButton;
|
|
||||||
self.smsWaitCountdownNode.getChildByName('WaitTimeLabel').getComponent(cc.Label).string = 20;
|
|
||||||
self.smsLoginCaptchaButton.on('click', self.onSMSCaptchaGetButtonClicked);
|
|
||||||
clearInterval(self.countdownTimer);
|
|
||||||
} else {
|
|
||||||
total--;
|
|
||||||
self.smsWaitCountdownNode.getChildByName('WaitTimeLabel').getComponent(cc.Label).string = total;
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
checkIntAuthTokenExpire() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!cc.sys.localStorage.getItem("selfPlayer")) {
|
|
||||||
reject();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const selfPlayer = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
|
|
||||||
(selfPlayer.intAuthToken && new Date().getTime() < selfPlayer.expiresAt) ? resolve() : reject();
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
checkPhoneNumber(type) {
|
|
||||||
const self = this;
|
|
||||||
const phoneNumberRegexp = self.regexList.PHONE;
|
|
||||||
var phoneNumberString = self.phoneNumberInput.getComponent(cc.EditBox).string;
|
|
||||||
if (phoneNumberString) {
|
|
||||||
return true;
|
|
||||||
if (!phoneNumberRegexp.test(phoneNumberString)) {
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.PHONE_ERR");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (type === 'getCaptcha' || type === 'login') {
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.PHONE_ERR");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
checkCaptcha(type) {
|
|
||||||
const self = this;
|
|
||||||
const captchaRegexp = self.regexList.SMS_CAPTCHA_CODE;
|
|
||||||
var captchaString = self.smsLoginCaptchaInput.getComponent(cc.EditBox).string;
|
|
||||||
|
|
||||||
if (captchaString) {
|
|
||||||
if (self.smsLoginCaptchaInput.getComponent(cc.EditBox).string.length !== 4 || (!captchaRegexp.test(captchaString))) {
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.CAPTCHA_ERR");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (type === 'login') {
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.CAPTCHA_ERR");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
useTokenLogin(_intAuthToken) {
|
|
||||||
var self = this;
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
url: backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER + constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.INT_AUTH_TOKEN + constants.ROUTE_PATH.LOGIN,
|
|
||||||
type: "POST",
|
|
||||||
data: {
|
|
||||||
intAuthToken: _intAuthToken
|
|
||||||
},
|
|
||||||
success: function(resp) {
|
|
||||||
self.onLoggedIn(resp);
|
|
||||||
},
|
|
||||||
error: function(xhr, status, errMsg) {
|
|
||||||
console.log("Login attempt `useTokenLogin` failed, about to execute `clearBoundRoomIdInBothVolatileAndPersistentStorage`.");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage()
|
|
||||||
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"));
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
},
|
|
||||||
timeout: function() {
|
|
||||||
self.enableInteractiveControls(true);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
enableInteractiveControls(enabled) {},
|
|
||||||
|
|
||||||
onLoginButtonClicked(evt) {
|
|
||||||
const self = this;
|
|
||||||
if (!self.checkPhoneNumber('login') || !self.checkCaptcha('login')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.loginParams = {
|
|
||||||
phoneCountryCode: self.phoneCountryCodeInput.getComponent(cc.EditBox).string,
|
|
||||||
phoneNum: self.phoneNumberInput.getComponent(cc.EditBox).string,
|
|
||||||
smsLoginCaptcha: self.smsLoginCaptchaInput.getComponent(cc.EditBox).string
|
|
||||||
};
|
|
||||||
self.enableInteractiveControls(false);
|
|
||||||
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
url: backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER +
|
|
||||||
constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.SMS_CAPTCHA + constants.ROUTE_PATH.LOGIN,
|
|
||||||
type: "POST",
|
|
||||||
data: self.loginParams,
|
|
||||||
success: function(resp) {
|
|
||||||
self.onLoggedIn(resp);
|
|
||||||
},
|
|
||||||
error: function(xhr, status, errMsg) {
|
|
||||||
console.log("Login attempt `onLoginButtonClicked` failed, about to execute `clearBoundRoomIdInBothVolatileAndPersistentStorage`.");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage()
|
|
||||||
},
|
|
||||||
timeout: function() {
|
|
||||||
self.enableInteractiveControls(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onWechatLoggedIn(res) {
|
|
||||||
const self = this;
|
|
||||||
if (constants.RET_CODE.OK == res.ret) {
|
|
||||||
//根据服务器返回信息设置selfPlayer
|
|
||||||
self.enableInteractiveControls(false);
|
|
||||||
const date = Number(res.expiresAt);
|
|
||||||
const selfPlayer = {
|
|
||||||
expiresAt: date,
|
|
||||||
playerId: res.playerId,
|
|
||||||
intAuthToken: res.intAuthToken,
|
|
||||||
displayName: res.displayName,
|
|
||||||
avatar: res.avatar,
|
|
||||||
}
|
|
||||||
cc.sys.localStorage.setItem('selfPlayer', JSON.stringify(selfPlayer));
|
|
||||||
|
|
||||||
self.useTokenLogin(res.intAuthToken);
|
|
||||||
} else {
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
|
|
||||||
self.showTips(i18n.t("login.tips.WECHAT_LOGIN_FAILED_TAP_SCREEN_TO_RETRY") + ", errorCode = " + res.ret);
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onLoggedIn(res) {
|
|
||||||
const self = this;
|
|
||||||
console.log("OnLoggedIn: ", res);
|
|
||||||
if (constants.RET_CODE.OK == res.ret) {
|
|
||||||
if (window.isUsingX5BlinkKernelOrWebkitWeChatKernel()) {
|
|
||||||
window.initWxSdk = self.initWxSdk.bind(self);
|
|
||||||
window.initWxSdk();
|
|
||||||
}
|
|
||||||
self.enableInteractiveControls(false);
|
|
||||||
const date = Number(res.expiresAt);
|
|
||||||
const selfPlayer = {
|
|
||||||
expiresAt: date,
|
|
||||||
playerId: res.playerId,
|
|
||||||
intAuthToken: res.intAuthToken,
|
|
||||||
avatar: res.avatar,
|
|
||||||
displayName: res.displayName,
|
|
||||||
name: res.name,
|
|
||||||
}
|
|
||||||
cc.sys.localStorage.setItem("selfPlayer", JSON.stringify(selfPlayer));
|
|
||||||
console.log("cc.sys.localStorage.selfPlayer = ", cc.sys.localStorage.getItem("selfPlayer"));
|
|
||||||
if (self.countdownTimer) {
|
|
||||||
clearInterval(self.countdownTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
cc.director.loadScene('default_map');
|
|
||||||
} else {
|
|
||||||
console.warn('onLoggedIn failed!')
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
self.enableInteractiveControls(true);
|
|
||||||
switch (res.ret) {
|
|
||||||
case constants.RET_CODE.DUPLICATED:
|
|
||||||
this.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.DUPLICATED");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.TOKEN_EXPIRED:
|
|
||||||
this.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.LOGIN_TOKEN_EXPIRED");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.SMS_CAPTCHA_NOT_MATCH:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.SMS_CAPTCHA_NOT_MATCH");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.INCORRECT_CAPTCHA:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.SMS_CAPTCHA_NOT_MATCH");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.SMS_CAPTCHA_CODE_NOT_EXISTING:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.SMS_CAPTCHA_NOT_MATCH");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.INCORRECT_PHONE_NUMBER:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.INCORRECT_PHONE_NUMBER");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.INVALID_REQUEST_PARAM:
|
|
||||||
self.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.INCORRECT_PHONE_NUMBER");
|
|
||||||
break;
|
|
||||||
case constants.RET_CODE.INCORRECT_PHONE_COUNTRY_CODE:
|
|
||||||
case constants.RET_CODE.INCORRECT_PHONE_NUMBER:
|
|
||||||
this.captchaTips.getComponent(cc.Label).string = i18n.t("login.tips.INCORRECT_PHONE_NUMBER");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.showTips(i18n.t("login.tips.AUTO_LOGIN_FAILED_WILL_USE_MANUAL_LOGIN"));
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
useWXCodeLogin(_code) {
|
|
||||||
const self = this;
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
url: backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER + constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.WECHAT + constants.ROUTE_PATH.LOGIN,
|
|
||||||
type: "POST",
|
|
||||||
data: {
|
|
||||||
code: _code
|
|
||||||
},
|
|
||||||
success: function(res) {
|
|
||||||
self.onWechatLoggedIn(res);
|
|
||||||
},
|
|
||||||
error: function(xhr, status, errMsg) {
|
|
||||||
console.log("Login attempt `onLoginButtonClicked` failed, about to execute `clearBoundRoomIdInBothVolatileAndPersistentStorage`.");
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
self.showTips(i18n.t("login.tips.WECHAT_LOGIN_FAILED_TAP_SCREEN_TO_RETRY") + ", errorMsg =" + errMsg);
|
|
||||||
},
|
|
||||||
timeout: function() {
|
|
||||||
console.log("Login attempt `onLoginButtonClicked` timed out, about to execute `clearBoundRoomIdInBothVolatileAndPersistentStorage`.");
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
self.showTips(i18n.t("login.tips.WECHAT_LOGIN_FAILED_TAP_SCREEN_TO_RETRY") + ", errorMsg =" + errMsg);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 对比useWxCodeLogin函数只是请求了不同url
|
|
||||||
useWxCodeMiniGameLogin(_code, _userInfo) {
|
|
||||||
const self = this;
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
url: backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER + constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.WECHATGAME + constants.ROUTE_PATH.LOGIN,
|
|
||||||
type: "POST",
|
|
||||||
data: {
|
|
||||||
code: _code,
|
|
||||||
avatarUrl: _userInfo.avatarUrl,
|
|
||||||
nickName: _userInfo.nickName,
|
|
||||||
},
|
|
||||||
success: function(res) {
|
|
||||||
self.onWechatLoggedIn(res);
|
|
||||||
},
|
|
||||||
error: function(xhr, status, errMsg) {
|
|
||||||
console.log("Login attempt `onLoginButtonClicked` failed, about to execute `clearBoundRoomIdInBothVolatileAndPersistentStorage`.");
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
self.showTips(i18n.t("login.tips.WECHAT_LOGIN_FAILED_TAP_SCREEN_TO_RETRY") + ", errorMsg =" + errMsg);
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
},
|
|
||||||
timeout: function() {
|
|
||||||
console.log("Login attempt `onLoginButtonClicked` failed, about to execute `clearBoundRoomIdInBothVolatileAndPersistentStorage`.");
|
|
||||||
cc.sys.localStorage.removeItem("selfPlayer");
|
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
|
||||||
self.showTips(i18n.t("login.tips.WECHAT_LOGIN_FAILED_TAP_SCREEN_TO_RETRY"));
|
|
||||||
self.createAuthorizeThenLoginButton();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getWechatCode(evt) {
|
|
||||||
let self = this;
|
|
||||||
self.showTips("");
|
|
||||||
const wechatServerEndpoint = wechatAddress.PROTOCOL + "://" + wechatAddress.HOST + ((null != wechatAddress.PORT && "" != wechatAddress.PORT.trim()) ? (":" + wechatAddress.PORT) : "");
|
|
||||||
const url = wechatServerEndpoint + constants.WECHAT.AUTHORIZE_PATH + "?" + wechatAddress.APPID_LITERAL + "&" + constants.WECHAT.REDIRECT_RUI_KEY + NetworkUtils.encode(window.location.href) + "&" + constants.WECHAT.RESPONSE_TYPE + "&" + constants.WECHAT.SCOPE + constants.WECHAT.FIN;
|
|
||||||
console.log("To visit wechat auth addr: ", url);
|
|
||||||
window.location.href = url;
|
|
||||||
},
|
|
||||||
|
|
||||||
initWxSdk() {
|
|
||||||
const selfPlayer = JSON.parse(cc.sys.localStorage.getItem('selfPlayer'));
|
|
||||||
const origUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
|
||||||
/*
|
|
||||||
* The `shareLink` must
|
|
||||||
* - have its 2nd-order-domain registered as trusted 2nd-order under the targetd `res.jsConfig.app_id`, and
|
|
||||||
* - extracted from current window.location.href.
|
|
||||||
*/
|
|
||||||
const shareLink = origUrl;
|
|
||||||
const updateAppMsgShareDataObj = {
|
|
||||||
type: 'link', // 分享类型,music、video或link,不填默认为link
|
|
||||||
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
|
|
||||||
title: document.title, // 分享标题
|
|
||||||
desc: 'Let\'s play together!', // 分享描述
|
|
||||||
link: shareLink + (cc.sys.localStorage.getItem('boundRoomId') ? "" : ("?expectedRoomId=" + cc.sys.localStorage.getItem('boundRoomId'))),
|
|
||||||
imgUrl: origUrl + "/favicon.ico", // 分享图标
|
|
||||||
success: function() {
|
|
||||||
// 设置成功
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const menuShareTimelineObj = {
|
|
||||||
title: document.title, // 分享标题
|
|
||||||
link: shareLink + (cc.sys.localStorage.getItem('boundRoomId') ? "" : ("?expectedRoomId=" + cc.sys.localStorage.getItem('boundRoomId'))),
|
|
||||||
imgUrl: origUrl + "/favicon.ico", // 分享图标
|
|
||||||
success: function() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
const wxConfigUrl = (window.isUsingWebkitWechatKernel() ? window.atFirstLocationHref : window.location.href);
|
|
||||||
|
|
||||||
//接入微信登录接口
|
|
||||||
NetworkUtils.ajax({
|
|
||||||
"url": backendAddress.PROTOCOL + '://' + backendAddress.HOST + ':' + backendAddress.PORT + constants.ROUTE_PATH.API + constants.ROUTE_PATH.PLAYER + constants.ROUTE_PATH.VERSION + constants.ROUTE_PATH.WECHAT + constants.ROUTE_PATH.JSCONFIG,
|
|
||||||
type: "POST",
|
|
||||||
data: {
|
|
||||||
"url": wxConfigUrl,
|
|
||||||
"intAuthToken": selfPlayer.intAuthToken,
|
|
||||||
},
|
|
||||||
success: function(res) {
|
|
||||||
if (constants.RET_CODE.OK != res.ret) {
|
|
||||||
console.warn("Failed to get `wsConfig`: ", res);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const jsConfig = res.jsConfig;
|
|
||||||
const configData = {
|
|
||||||
debug: CC_DEBUG, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
|
|
||||||
appId: jsConfig.app_id, // 必填,公众号的唯一标识
|
|
||||||
timestamp: jsConfig.timestamp.toString(), // 必填,生成签名的时间戳
|
|
||||||
nonceStr: jsConfig.nonce_str, // 必填,生成签名的随机串
|
|
||||||
jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline'],
|
|
||||||
signature: jsConfig.signature, // 必填,签名
|
|
||||||
};
|
|
||||||
console.log("config url: ", wxConfigUrl);
|
|
||||||
console.log("wx.config: ", configData);
|
|
||||||
wx.config(configData);
|
|
||||||
console.log("Current window.location.href: ", window.location.href);
|
|
||||||
wx.ready(function() {
|
|
||||||
console.log("Here is wx.ready.")
|
|
||||||
wx.onMenuShareAppMessage(updateAppMsgShareDataObj);
|
|
||||||
wx.onMenuShareTimeline(menuShareTimelineObj);
|
|
||||||
});
|
|
||||||
wx.error(function(res) {
|
|
||||||
console.error("wx config fails and error is ", JSON.stringify(res));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
error: function(xhr, status, errMsg) {
|
|
||||||
console.error("Failed to get `wsConfig`: ", errMsg);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
update(dt) {
|
|
||||||
const self = this;
|
|
||||||
if (null != wxDownloader && 0 < wxDownloader.totalBytesExpectedToWriteForAllTasks) {
|
|
||||||
self.writtenBytes.string = wxDownloader.totalBytesWrittenForAllTasks;
|
|
||||||
self.expectedToWriteBytes.string = wxDownloader.totalBytesExpectedToWriteForAllTasks;
|
|
||||||
self.downloadProgress.progress = 1.0*wxDownloader.totalBytesWrittenForAllTasks/wxDownloader.totalBytesExpectedToWriteForAllTasks;
|
|
||||||
}
|
|
||||||
const totalUrlsToHandle = (wxDownloader.immediateHandleItemCount + wxDownloader.immediateReadFromLocalCount + wxDownloader.immediatePackDownloaderCount);
|
|
||||||
const totalUrlsHandled = (wxDownloader.immediateHandleItemCompleteCount + wxDownloader.immediateReadFromLocalCompleteCount + wxDownloader.immediatePackDownloaderCompleteCount);
|
|
||||||
if (null != wxDownloader && 0 < totalUrlsToHandle) {
|
|
||||||
self.handledUrlsCount.string = totalUrlsHandled;
|
|
||||||
self.toHandledUrlsCount.string = totalUrlsToHandle;
|
|
||||||
self.handlerProgress.progress = 1.0*totalUrlsHandled/totalUrlsToHandle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
@ -74,8 +74,6 @@ function _base64ToUint8Array(base64) {
|
|||||||
origBytes[i] = origBinaryStr.charCodeAt(i);
|
origBytes[i] = origBinaryStr.charCodeAt(i);
|
||||||
}
|
}
|
||||||
return origBytes;
|
return origBytes;
|
||||||
} else if (cc.sys.platform == cc.sys.WECHAT_GAME) {
|
|
||||||
return Buffer.from(base64, 'base64');
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -86,16 +84,12 @@ function _base64ToArrayBuffer(base64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.getExpectedRoomIdSync = function() {
|
window.getExpectedRoomIdSync = function() {
|
||||||
if (cc.sys.platform == cc.sys.WECHAT_GAME) {
|
const qDict = window.getQueryParamDict();
|
||||||
return window.expectedRoomId;
|
if (qDict) {
|
||||||
|
return qDict["expectedRoomId"];
|
||||||
} else {
|
} else {
|
||||||
const qDict = window.getQueryParamDict();
|
if (window.history && window.history.state) {
|
||||||
if (qDict) {
|
return window.history.state.expectedRoomId;
|
||||||
return qDict["expectedRoomId"];
|
|
||||||
} else {
|
|
||||||
if (window.history && window.history.state) {
|
|
||||||
return window.history.state.expectedRoomId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,10 +123,6 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
|
|||||||
if (null != expectedRoomId) {
|
if (null != expectedRoomId) {
|
||||||
console.log("initPersistentSessionClient with expectedRoomId == " + expectedRoomId);
|
console.log("initPersistentSessionClient with expectedRoomId == " + expectedRoomId);
|
||||||
urlToConnect = urlToConnect + "&expectedRoomId=" + expectedRoomId;
|
urlToConnect = urlToConnect + "&expectedRoomId=" + expectedRoomId;
|
||||||
if (cc.sys.platform == cc.sys.WECHAT_GAME) {
|
|
||||||
// This is a dirty hack. -- YFLu
|
|
||||||
window.expectedRoomId = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
window.boundRoomId = getBoundRoomIdFromPersistentStorage();
|
window.boundRoomId = getBoundRoomIdFromPersistentStorage();
|
||||||
if (null != window.boundRoomId) {
|
if (null != window.boundRoomId) {
|
||||||
@ -143,10 +133,6 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
|
|||||||
|
|
||||||
const currentHistoryState = window.history && window.history.state ? window.history.state : {};
|
const currentHistoryState = window.history && window.history.state ? window.history.state : {};
|
||||||
|
|
||||||
if (cc.sys.platform != cc.sys.WECHAT_GAME) {
|
|
||||||
window.history.replaceState(currentHistoryState, document.title, window.location.pathname);
|
|
||||||
}
|
|
||||||
|
|
||||||
const clientSession = new WebSocket(urlToConnect);
|
const clientSession = new WebSocket(urlToConnect);
|
||||||
clientSession.binaryType = 'arraybuffer'; // Make 'event.data' of 'onmessage' an "ArrayBuffer" instead of a "Blob"
|
clientSession.binaryType = 'arraybuffer'; // Make 'event.data' of 'onmessage' an "ArrayBuffer" instead of a "Blob"
|
||||||
|
|
||||||
@ -254,10 +240,6 @@ window.clearLocalStorageAndBackToLoginScene = function(shouldRetainBoundRoomIdIn
|
|||||||
if (true != shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) {
|
if (true != shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) {
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
||||||
}
|
}
|
||||||
if (cc.sys.platform == cc.sys.WECHAT_GAME) {
|
cc.director.loadScene('login');
|
||||||
cc.director.loadScene('wechatGameLogin');
|
|
||||||
} else {
|
|
||||||
cc.director.loadScene('login');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
197
frontend/assets/scripts/modules/Collisions.js
Normal file
197
frontend/assets/scripts/modules/Collisions.js
Normal file
File diff suppressed because one or more lines are too long
9
frontend/assets/scripts/modules/Collisions.js.meta
Normal file
9
frontend/assets/scripts/modules/Collisions.js.meta
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.0.5",
|
||||||
|
"uuid": "da0a517f-5c74-4fc0-ba89-dbcee184b13e",
|
||||||
|
"isPlugin": false,
|
||||||
|
"loadPluginInWeb": true,
|
||||||
|
"loadPluginInNative": true,
|
||||||
|
"loadPluginInEditor": false,
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@ -4343,7 +4343,6 @@ $root.treasurehunterx = (function() {
|
|||||||
* @property {Object.<string,treasurehunterx.Trap>|null} [traps] RoomDownsyncFrame traps
|
* @property {Object.<string,treasurehunterx.Trap>|null} [traps] RoomDownsyncFrame traps
|
||||||
* @property {Object.<string,treasurehunterx.Bullet>|null} [bullets] RoomDownsyncFrame bullets
|
* @property {Object.<string,treasurehunterx.Bullet>|null} [bullets] RoomDownsyncFrame bullets
|
||||||
* @property {Object.<string,treasurehunterx.SpeedShoe>|null} [speedShoes] RoomDownsyncFrame speedShoes
|
* @property {Object.<string,treasurehunterx.SpeedShoe>|null} [speedShoes] RoomDownsyncFrame speedShoes
|
||||||
* @property {Object.<string,treasurehunterx.Pumpkin>|null} [pumpkin] RoomDownsyncFrame pumpkin
|
|
||||||
* @property {Object.<string,treasurehunterx.GuardTower>|null} [guardTowers] RoomDownsyncFrame guardTowers
|
* @property {Object.<string,treasurehunterx.GuardTower>|null} [guardTowers] RoomDownsyncFrame guardTowers
|
||||||
* @property {Object.<string,treasurehunterx.PlayerMeta>|null} [playerMetas] RoomDownsyncFrame playerMetas
|
* @property {Object.<string,treasurehunterx.PlayerMeta>|null} [playerMetas] RoomDownsyncFrame playerMetas
|
||||||
*/
|
*/
|
||||||
@ -4362,7 +4361,6 @@ $root.treasurehunterx = (function() {
|
|||||||
this.traps = {};
|
this.traps = {};
|
||||||
this.bullets = {};
|
this.bullets = {};
|
||||||
this.speedShoes = {};
|
this.speedShoes = {};
|
||||||
this.pumpkin = {};
|
|
||||||
this.guardTowers = {};
|
this.guardTowers = {};
|
||||||
this.playerMetas = {};
|
this.playerMetas = {};
|
||||||
if (properties)
|
if (properties)
|
||||||
@ -4443,14 +4441,6 @@ $root.treasurehunterx = (function() {
|
|||||||
*/
|
*/
|
||||||
RoomDownsyncFrame.prototype.speedShoes = $util.emptyObject;
|
RoomDownsyncFrame.prototype.speedShoes = $util.emptyObject;
|
||||||
|
|
||||||
/**
|
|
||||||
* RoomDownsyncFrame pumpkin.
|
|
||||||
* @member {Object.<string,treasurehunterx.Pumpkin>} pumpkin
|
|
||||||
* @memberof treasurehunterx.RoomDownsyncFrame
|
|
||||||
* @instance
|
|
||||||
*/
|
|
||||||
RoomDownsyncFrame.prototype.pumpkin = $util.emptyObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RoomDownsyncFrame guardTowers.
|
* RoomDownsyncFrame guardTowers.
|
||||||
* @member {Object.<string,treasurehunterx.GuardTower>} guardTowers
|
* @member {Object.<string,treasurehunterx.GuardTower>} guardTowers
|
||||||
@ -4524,19 +4514,14 @@ $root.treasurehunterx = (function() {
|
|||||||
writer.uint32(/* id 9, wireType 2 =*/74).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
writer.uint32(/* id 9, wireType 2 =*/74).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
||||||
$root.treasurehunterx.SpeedShoe.encode(message.speedShoes[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
$root.treasurehunterx.SpeedShoe.encode(message.speedShoes[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
||||||
}
|
}
|
||||||
if (message.pumpkin != null && Object.hasOwnProperty.call(message, "pumpkin"))
|
|
||||||
for (var keys = Object.keys(message.pumpkin), i = 0; i < keys.length; ++i) {
|
|
||||||
writer.uint32(/* id 10, wireType 2 =*/82).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
|
||||||
$root.treasurehunterx.Pumpkin.encode(message.pumpkin[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
|
||||||
}
|
|
||||||
if (message.guardTowers != null && Object.hasOwnProperty.call(message, "guardTowers"))
|
if (message.guardTowers != null && Object.hasOwnProperty.call(message, "guardTowers"))
|
||||||
for (var keys = Object.keys(message.guardTowers), i = 0; i < keys.length; ++i) {
|
for (var keys = Object.keys(message.guardTowers), i = 0; i < keys.length; ++i) {
|
||||||
writer.uint32(/* id 11, wireType 2 =*/90).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
writer.uint32(/* id 10, wireType 2 =*/82).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
||||||
$root.treasurehunterx.GuardTower.encode(message.guardTowers[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
$root.treasurehunterx.GuardTower.encode(message.guardTowers[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
||||||
}
|
}
|
||||||
if (message.playerMetas != null && Object.hasOwnProperty.call(message, "playerMetas"))
|
if (message.playerMetas != null && Object.hasOwnProperty.call(message, "playerMetas"))
|
||||||
for (var keys = Object.keys(message.playerMetas), i = 0; i < keys.length; ++i) {
|
for (var keys = Object.keys(message.playerMetas), i = 0; i < keys.length; ++i) {
|
||||||
writer.uint32(/* id 12, wireType 2 =*/98).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
writer.uint32(/* id 11, wireType 2 =*/90).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
||||||
$root.treasurehunterx.PlayerMeta.encode(message.playerMetas[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
$root.treasurehunterx.PlayerMeta.encode(message.playerMetas[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
||||||
}
|
}
|
||||||
return writer;
|
return writer;
|
||||||
@ -4705,29 +4690,6 @@ $root.treasurehunterx = (function() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 10: {
|
case 10: {
|
||||||
if (message.pumpkin === $util.emptyObject)
|
|
||||||
message.pumpkin = {};
|
|
||||||
var end2 = reader.uint32() + reader.pos;
|
|
||||||
key = 0;
|
|
||||||
value = null;
|
|
||||||
while (reader.pos < end2) {
|
|
||||||
var tag2 = reader.uint32();
|
|
||||||
switch (tag2 >>> 3) {
|
|
||||||
case 1:
|
|
||||||
key = reader.int32();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
value = $root.treasurehunterx.Pumpkin.decode(reader, reader.uint32());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
reader.skipType(tag2 & 7);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
message.pumpkin[key] = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 11: {
|
|
||||||
if (message.guardTowers === $util.emptyObject)
|
if (message.guardTowers === $util.emptyObject)
|
||||||
message.guardTowers = {};
|
message.guardTowers = {};
|
||||||
var end2 = reader.uint32() + reader.pos;
|
var end2 = reader.uint32() + reader.pos;
|
||||||
@ -4750,7 +4712,7 @@ $root.treasurehunterx = (function() {
|
|||||||
message.guardTowers[key] = value;
|
message.guardTowers[key] = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 12: {
|
case 11: {
|
||||||
if (message.playerMetas === $util.emptyObject)
|
if (message.playerMetas === $util.emptyObject)
|
||||||
message.playerMetas = {};
|
message.playerMetas = {};
|
||||||
var end2 = reader.uint32() + reader.pos;
|
var end2 = reader.uint32() + reader.pos;
|
||||||
@ -4890,20 +4852,6 @@ $root.treasurehunterx = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message.pumpkin != null && message.hasOwnProperty("pumpkin")) {
|
|
||||||
if (!$util.isObject(message.pumpkin))
|
|
||||||
return "pumpkin: object expected";
|
|
||||||
var key = Object.keys(message.pumpkin);
|
|
||||||
for (var i = 0; i < key.length; ++i) {
|
|
||||||
if (!$util.key32Re.test(key[i]))
|
|
||||||
return "pumpkin: integer key{k:int32} expected";
|
|
||||||
{
|
|
||||||
var error = $root.treasurehunterx.Pumpkin.verify(message.pumpkin[key[i]]);
|
|
||||||
if (error)
|
|
||||||
return "pumpkin." + error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (message.guardTowers != null && message.hasOwnProperty("guardTowers")) {
|
if (message.guardTowers != null && message.hasOwnProperty("guardTowers")) {
|
||||||
if (!$util.isObject(message.guardTowers))
|
if (!$util.isObject(message.guardTowers))
|
||||||
return "guardTowers: object expected";
|
return "guardTowers: object expected";
|
||||||
@ -5019,16 +4967,6 @@ $root.treasurehunterx = (function() {
|
|||||||
message.speedShoes[keys[i]] = $root.treasurehunterx.SpeedShoe.fromObject(object.speedShoes[keys[i]]);
|
message.speedShoes[keys[i]] = $root.treasurehunterx.SpeedShoe.fromObject(object.speedShoes[keys[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (object.pumpkin) {
|
|
||||||
if (typeof object.pumpkin !== "object")
|
|
||||||
throw TypeError(".treasurehunterx.RoomDownsyncFrame.pumpkin: object expected");
|
|
||||||
message.pumpkin = {};
|
|
||||||
for (var keys = Object.keys(object.pumpkin), i = 0; i < keys.length; ++i) {
|
|
||||||
if (typeof object.pumpkin[keys[i]] !== "object")
|
|
||||||
throw TypeError(".treasurehunterx.RoomDownsyncFrame.pumpkin: object expected");
|
|
||||||
message.pumpkin[keys[i]] = $root.treasurehunterx.Pumpkin.fromObject(object.pumpkin[keys[i]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (object.guardTowers) {
|
if (object.guardTowers) {
|
||||||
if (typeof object.guardTowers !== "object")
|
if (typeof object.guardTowers !== "object")
|
||||||
throw TypeError(".treasurehunterx.RoomDownsyncFrame.guardTowers: object expected");
|
throw TypeError(".treasurehunterx.RoomDownsyncFrame.guardTowers: object expected");
|
||||||
@ -5071,7 +5009,6 @@ $root.treasurehunterx = (function() {
|
|||||||
object.traps = {};
|
object.traps = {};
|
||||||
object.bullets = {};
|
object.bullets = {};
|
||||||
object.speedShoes = {};
|
object.speedShoes = {};
|
||||||
object.pumpkin = {};
|
|
||||||
object.guardTowers = {};
|
object.guardTowers = {};
|
||||||
object.playerMetas = {};
|
object.playerMetas = {};
|
||||||
}
|
}
|
||||||
@ -5129,11 +5066,6 @@ $root.treasurehunterx = (function() {
|
|||||||
for (var j = 0; j < keys2.length; ++j)
|
for (var j = 0; j < keys2.length; ++j)
|
||||||
object.speedShoes[keys2[j]] = $root.treasurehunterx.SpeedShoe.toObject(message.speedShoes[keys2[j]], options);
|
object.speedShoes[keys2[j]] = $root.treasurehunterx.SpeedShoe.toObject(message.speedShoes[keys2[j]], options);
|
||||||
}
|
}
|
||||||
if (message.pumpkin && (keys2 = Object.keys(message.pumpkin)).length) {
|
|
||||||
object.pumpkin = {};
|
|
||||||
for (var j = 0; j < keys2.length; ++j)
|
|
||||||
object.pumpkin[keys2[j]] = $root.treasurehunterx.Pumpkin.toObject(message.pumpkin[keys2[j]], options);
|
|
||||||
}
|
|
||||||
if (message.guardTowers && (keys2 = Object.keys(message.guardTowers)).length) {
|
if (message.guardTowers && (keys2 = Object.keys(message.guardTowers)).length) {
|
||||||
object.guardTowers = {};
|
object.guardTowers = {};
|
||||||
for (var j = 0; j < keys2.length; ++j)
|
for (var j = 0; j < keys2.length; ++j)
|
||||||
|
@ -33,20 +33,21 @@
|
|||||||
"design-resolution-height": 640,
|
"design-resolution-height": 640,
|
||||||
"design-resolution-width": 960,
|
"design-resolution-width": 960,
|
||||||
"excluded-modules": [
|
"excluded-modules": [
|
||||||
"Spine Skeleton",
|
"Collider",
|
||||||
"DragonBones",
|
"DragonBones",
|
||||||
"RichText",
|
"Geom Utils",
|
||||||
|
"Mesh",
|
||||||
"MotionStreak",
|
"MotionStreak",
|
||||||
|
"Physics",
|
||||||
"PageView",
|
"PageView",
|
||||||
"PageViewIndicator",
|
"PageViewIndicator",
|
||||||
|
"RichText",
|
||||||
"Slider",
|
"Slider",
|
||||||
|
"Spine Skeleton",
|
||||||
|
"StudioComponent",
|
||||||
"VideoPlayer",
|
"VideoPlayer",
|
||||||
"WebView",
|
"WebView",
|
||||||
"Physics",
|
|
||||||
"StudioComponent",
|
|
||||||
"3D",
|
"3D",
|
||||||
"Mesh",
|
|
||||||
"Geom Utils",
|
|
||||||
"3D Primitive"
|
"3D Primitive"
|
||||||
],
|
],
|
||||||
"facebook": {
|
"facebook": {
|
||||||
@ -74,7 +75,7 @@
|
|||||||
"height": 640,
|
"height": 640,
|
||||||
"width": 960
|
"width": 960
|
||||||
},
|
},
|
||||||
"start-scene": "current",
|
"use-customize-simulator": true,
|
||||||
"use-customize-simulator": false,
|
"use-project-simulator-setting": false,
|
||||||
"use-project-simulator-setting": false
|
"start-scene": "current"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user