mirror of
https://github.com/CPunch/gopenfusion.git
synced 2024-11-10 02:20:05 +00:00
movement.go: added support for basic movement packets
you should be able to view other players and jump around together, although while testing locally one of the clients would always trigger the "Some irregularities have been found with your connection to the server, so your game will be closed" speed check for some reason ??? really not sure, might just be my machine chunking uhhh works ? kind of, not tested for more than a few seconds before one of the clients disconnects
This commit is contained in:
parent
f6ab7a9b5d
commit
8f00a0c492
@ -122,7 +122,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (db *DBHandler) readPlayer(rows *sql.Rows) (*entity.Player, error) {
|
func (db *DBHandler) readPlayer(rows *sql.Rows) (*entity.Player, error) {
|
||||||
plr := entity.Player{ActiveNanoSlotNum: -1}
|
plr := entity.Player{ActiveNanoSlotNum: 0}
|
||||||
|
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&plr.PlayerID, &plr.AccountID, &plr.Slot, &plr.PCStyle.SzFirstName, &plr.PCStyle.SzLastName,
|
&plr.PlayerID, &plr.AccountID, &plr.Slot, &plr.PCStyle.SzFirstName, &plr.PCStyle.SzLastName,
|
||||||
|
@ -28,11 +28,16 @@ func (c *Chunk) RemoveEntity(entity Entity) {
|
|||||||
|
|
||||||
// send packet to all peers in this chunk and kill each peer if error
|
// send packet to all peers in this chunk and kill each peer if error
|
||||||
func (c *Chunk) SendPacket(typeID uint32, pkt ...interface{}) {
|
func (c *Chunk) SendPacket(typeID uint32, pkt ...interface{}) {
|
||||||
|
c.SendPacketExclude(nil, typeID, pkt...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Chunk) SendPacketExclude(exclude Entity, typeID uint32, pkt ...interface{}) {
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
for entity := range c.Entities {
|
for entity := range c.Entities {
|
||||||
if entity.GetKind() != ENTITY_KIND_PLAYER {
|
// only send to players, and exclude the player that sent the packet
|
||||||
|
if entity.GetKind() != ENTITY_KIND_PLAYER || entity == exclude {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,6 @@ func (plr *Player) GetAppearanceData() protocol.SPCAppearanceData {
|
|||||||
PCStyle: plr.PCStyle,
|
PCStyle: plr.PCStyle,
|
||||||
IPCState: plr.IPCState,
|
IPCState: plr.IPCState,
|
||||||
ItemEquip: plr.Equip,
|
ItemEquip: plr.Equip,
|
||||||
Nano: protocol.SNano{}, //plr.Nanos[plr.ActiveNanoSlotNum],
|
Nano: plr.Nanos[plr.ActiveNanoSlotNum],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ func (server *ShardServer) getViewableChunks(pos entity.ChunkPosition) []*entity
|
|||||||
return chunks
|
return chunks
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *ShardServer) sendPacketToViewableChunks(plr *entity.Player, typeID uint32, pkt ...interface{}) error {
|
// sends a packet to all peers in the given chunks, excluding the given peer
|
||||||
for _, chunk := range server.getViewableChunks(plr.Chunk) {
|
func (server *ShardServer) sendOthersPacket(plr *entity.Player, typeID uint32, pkt ...interface{}) error {
|
||||||
chunk.SendPacket(typeID, pkt...)
|
chunks := server.getViewableChunks(plr.Chunk)
|
||||||
|
for _, chunk := range chunks {
|
||||||
|
chunk.SendPacketExclude(plr, typeID, pkt...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -34,11 +36,17 @@ func (server *ShardServer) sendPacketToViewableChunks(plr *entity.Player, typeID
|
|||||||
func (server *ShardServer) removeEntityFromChunks(chunks []*entity.Chunk, this entity.Entity) {
|
func (server *ShardServer) removeEntityFromChunks(chunks []*entity.Chunk, this entity.Entity) {
|
||||||
for _, chunk := range chunks {
|
for _, chunk := range chunks {
|
||||||
for e, _ := range chunk.Entities {
|
for e, _ := range chunk.Entities {
|
||||||
|
if e == this {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify other players we're leaving
|
||||||
if e.GetKind() == entity.ENTITY_KIND_PLAYER {
|
if e.GetKind() == entity.ENTITY_KIND_PLAYER {
|
||||||
otherPlr := e.(*entity.Player)
|
otherPlr := e.(*entity.Player)
|
||||||
this.DisappearFromViewOf(otherPlr.Peer)
|
this.DisappearFromViewOf(otherPlr.Peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notify us they're leaving
|
||||||
if this.GetKind() == entity.ENTITY_KIND_PLAYER {
|
if this.GetKind() == entity.ENTITY_KIND_PLAYER {
|
||||||
thisPlr := this.(*entity.Player)
|
thisPlr := this.(*entity.Player)
|
||||||
e.DisappearFromViewOf(thisPlr.Peer)
|
e.DisappearFromViewOf(thisPlr.Peer)
|
||||||
@ -50,11 +58,17 @@ func (server *ShardServer) removeEntityFromChunks(chunks []*entity.Chunk, this e
|
|||||||
func (server *ShardServer) addEntityToChunks(chunks []*entity.Chunk, this entity.Entity) {
|
func (server *ShardServer) addEntityToChunks(chunks []*entity.Chunk, this entity.Entity) {
|
||||||
for _, chunk := range chunks {
|
for _, chunk := range chunks {
|
||||||
for e, _ := range chunk.Entities {
|
for e, _ := range chunk.Entities {
|
||||||
|
if e == this {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify other players we're entering
|
||||||
if e.GetKind() == entity.ENTITY_KIND_PLAYER {
|
if e.GetKind() == entity.ENTITY_KIND_PLAYER {
|
||||||
otherPlr := e.(*entity.Player)
|
otherPlr := e.(*entity.Player)
|
||||||
this.EnterIntoViewOf(otherPlr.Peer)
|
this.EnterIntoViewOf(otherPlr.Peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notify us they're entering
|
||||||
if this.GetKind() == entity.ENTITY_KIND_PLAYER {
|
if this.GetKind() == entity.ENTITY_KIND_PLAYER {
|
||||||
thisPlr := this.(*entity.Player)
|
thisPlr := this.(*entity.Player)
|
||||||
e.EnterIntoViewOf(thisPlr.Peer)
|
e.EnterIntoViewOf(thisPlr.Peer)
|
||||||
@ -64,6 +78,11 @@ func (server *ShardServer) addEntityToChunks(chunks []*entity.Chunk, this entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (server *ShardServer) updateEntityChunk(e entity.Entity, from entity.ChunkPosition, to entity.ChunkPosition) {
|
func (server *ShardServer) updateEntityChunk(e entity.Entity, from entity.ChunkPosition, to entity.ChunkPosition) {
|
||||||
|
// no change needed
|
||||||
|
if from == to {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
oldViewables := server.getViewableChunks(from)
|
oldViewables := server.getViewableChunks(from)
|
||||||
newViewables := server.getViewableChunks(to)
|
newViewables := server.getViewableChunks(to)
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ func (server *ShardServer) RequestEnter(peer *protocol.CNPeer, pkt protocol.Pack
|
|||||||
|
|
||||||
log.Printf("Player %d (AccountID %d) entered\n", resp.IID, loginData.AccountID)
|
log.Printf("Player %d (AccountID %d) entered\n", resp.IID, loginData.AccountID)
|
||||||
|
|
||||||
server.updatePlayerPosition(peer, int(plr.X), int(plr.Y), int(plr.Z), int(plr.Angle))
|
server.updatePlayerPosition(plr, int(plr.X), int(plr.Y), int(plr.Z), int(plr.Angle))
|
||||||
return peer.Send(protocol.P_FE2CL_REP_PC_ENTER_SUCC, resp)
|
return peer.Send(protocol.P_FE2CL_REP_PC_ENTER_SUCC, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,18 @@
|
|||||||
package shard
|
package shard
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/CPunch/gopenfusion/core/entity"
|
"github.com/CPunch/gopenfusion/core/entity"
|
||||||
"github.com/CPunch/gopenfusion/core/protocol"
|
"github.com/CPunch/gopenfusion/core/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (server *ShardServer) updatePlayerPosition(peer *protocol.CNPeer, X, Y, Z, Angle int) error {
|
func (server *ShardServer) updatePlayerPosition(plr *entity.Player, X, Y, Z, Angle int) error {
|
||||||
plr, err := server.getPlayer(peer)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
newPos := entity.MakeChunkPosition(X, Y)
|
|
||||||
oldPos := plr.Chunk
|
|
||||||
|
|
||||||
plr.X = X
|
plr.X = X
|
||||||
plr.Y = Y
|
plr.Y = Y
|
||||||
plr.Z = Z
|
plr.Z = Z
|
||||||
plr.Angle = Angle
|
plr.Angle = Angle
|
||||||
if newPos != oldPos {
|
server.updateEntityChunk(plr, plr.GetChunk(), entity.MakeChunkPosition(X, Y))
|
||||||
server.updateEntityChunk(plr, oldPos, newPos)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,5 +20,85 @@ func (server *ShardServer) playerMove(peer *protocol.CNPeer, pkt protocol.Packet
|
|||||||
var move protocol.SP_CL2FE_REQ_PC_MOVE
|
var move protocol.SP_CL2FE_REQ_PC_MOVE
|
||||||
pkt.Decode(&move)
|
pkt.Decode(&move)
|
||||||
|
|
||||||
return server.updatePlayerPosition(peer, int(move.IX), int(move.IY), int(move.IZ), int(move.IAngle))
|
// sanity check
|
||||||
|
plr, err := server.getPlayer(peer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update chunking
|
||||||
|
if err := server.updatePlayerPosition(plr, int(move.IX), int(move.IY), int(move.IZ), int(move.IAngle)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return server.sendOthersPacket(plr, protocol.P_FE2CL_PC_MOVE, protocol.SP_FE2CL_PC_MOVE{
|
||||||
|
ICliTime: uint64(time.Now().Unix()),
|
||||||
|
IX: move.IX,
|
||||||
|
IY: move.IY,
|
||||||
|
IZ: move.IZ,
|
||||||
|
FVX: move.FVX,
|
||||||
|
FVY: move.FVY,
|
||||||
|
FVZ: move.FVZ,
|
||||||
|
IAngle: move.IAngle,
|
||||||
|
CKeyValue: move.CKeyValue,
|
||||||
|
ISpeed: move.ISpeed,
|
||||||
|
IID: int32(plr.PlayerID),
|
||||||
|
ISvrTime: uint64(time.Now().Unix()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (server *ShardServer) playerStop(peer *protocol.CNPeer, pkt protocol.Packet) error {
|
||||||
|
var stop protocol.SP_CL2FE_REQ_PC_STOP
|
||||||
|
pkt.Decode(&stop)
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
plr, err := server.getPlayer(peer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update chunking
|
||||||
|
if err := server.updatePlayerPosition(plr, int(stop.IX), int(stop.IY), int(stop.IZ), plr.Angle); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return server.sendOthersPacket(plr, protocol.P_FE2CL_PC_STOP, protocol.SP_FE2CL_PC_STOP{
|
||||||
|
ICliTime: uint64(time.Now().Unix()),
|
||||||
|
IX: stop.IX,
|
||||||
|
IY: stop.IY,
|
||||||
|
IZ: stop.IZ,
|
||||||
|
IID: int32(plr.PlayerID),
|
||||||
|
ISvrTime: uint64(time.Now().Unix()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (server *ShardServer) playerJump(peer *protocol.CNPeer, pkt protocol.Packet) error {
|
||||||
|
var jump protocol.SP_CL2FE_REQ_PC_JUMP
|
||||||
|
pkt.Decode(&jump)
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
plr, err := server.getPlayer(peer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update chunking
|
||||||
|
if err := server.updatePlayerPosition(plr, int(jump.IX), int(jump.IY), int(jump.IZ), plr.Angle); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return server.sendOthersPacket(plr, protocol.P_FE2CL_PC_JUMP, protocol.SP_FE2CL_PC_JUMP{
|
||||||
|
ICliTime: uint64(time.Now().Unix()),
|
||||||
|
IX: jump.IX,
|
||||||
|
IY: jump.IY,
|
||||||
|
IZ: jump.IZ,
|
||||||
|
IVX: jump.IVX,
|
||||||
|
IVY: jump.IVY,
|
||||||
|
IVZ: jump.IVZ,
|
||||||
|
IAngle: jump.IAngle,
|
||||||
|
CKeyValue: jump.CKeyValue,
|
||||||
|
ISpeed: jump.ISpeed,
|
||||||
|
IID: int32(plr.PlayerID),
|
||||||
|
ISvrTime: uint64(time.Now().Unix()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,9 @@ func NewShardServer(dbHndlr *db.DBHandler, redisHndlr *redis.RedisHandler, port
|
|||||||
server.packetHandlers = map[uint32]PacketHandler{
|
server.packetHandlers = map[uint32]PacketHandler{
|
||||||
protocol.P_CL2FE_REQ_PC_ENTER: server.RequestEnter,
|
protocol.P_CL2FE_REQ_PC_ENTER: server.RequestEnter,
|
||||||
protocol.P_CL2FE_REQ_PC_LOADING_COMPLETE: server.LoadingComplete,
|
protocol.P_CL2FE_REQ_PC_LOADING_COMPLETE: server.LoadingComplete,
|
||||||
|
protocol.P_CL2FE_REQ_PC_MOVE: server.playerMove,
|
||||||
|
protocol.P_CL2FE_REQ_PC_STOP: server.playerStop,
|
||||||
|
protocol.P_CL2FE_REQ_PC_JUMP: server.playerJump,
|
||||||
}
|
}
|
||||||
|
|
||||||
redisHndlr.RegisterShard(redis.ShardMetadata{
|
redisHndlr.RegisterShard(redis.ShardMetadata{
|
||||||
|
Loading…
Reference in New Issue
Block a user