Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin ao #110

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions client_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ func handleClt(cc *ClientConn) {
if errors.Is(cc.WhyClosed(), rudp.ErrTimedOut) {
cc.Log("<->", "timeout")
} else {
handlePlayerLeave(cc, &Leave{
Type: Exit,
})
cc.Log("<->", "disconnect")
}

Expand Down
4 changes: 4 additions & 0 deletions content.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ func muxNodeDefs(conns []*contentConn) (nodeDefs []mt.NodeDef, p0Map param0Map,
}

def.Param0 = param0
oldName := def.Name // copy string to use later
prepend(cc.mediaPool, &def.Name)
prepend(cc.mediaPool, &def.Mesh)
for i := range def.Tiles {
Expand All @@ -456,6 +457,9 @@ func muxNodeDefs(conns []*contentConn) (nodeDefs []mt.NodeDef, p0Map param0Map,
if param0 >= mt.Unknown && param0 <= mt.Ignore {
param0 = mt.Ignore + 1
}

// add nodeid (if reqested)
addNodeId(oldName, def.Param0)
}
}

Expand Down
4 changes: 4 additions & 0 deletions hop.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ func (cc *ClientConn) Hop(serverName string) error {

cc.Log("<->", "hop", serverName)

source := cc.ServerName()

if cc.server() == nil {
err := fmt.Errorf("no server connection")
cc.Log("<->", err)
Expand Down Expand Up @@ -160,5 +162,7 @@ func (cc *ClientConn) Hop(serverName string) error {
return authIface.SetLastSrv(cc.Name(), serverName)
}

handlePlayerHop(cc, source, serverName)

return nil
}
9 changes: 8 additions & 1 deletion moderation.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ import (
// and closes the ClientConn.
func (cc *ClientConn) Kick(reason string) {
go func() {
ack, _ := cc.SendCmd(&mt.ToCltKick{
kick := &mt.ToCltKick{
Reason: mt.Custom,
Custom: reason,
}

ack, _ := cc.SendCmd(kick)

handlePlayerLeave(cc ,&Leave{
Type: Kick,
Kick: kick,
})

select {
Expand Down
251 changes: 251 additions & 0 deletions plugin_AO.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package proxy

import (
"github.com/anon55555/mt"
"sync"
)

type AOHandler struct {
AOIDs map[string]map[mt.AOID]bool

OnAOMsg func(*ClientConn, mt.AOID, mt.AOMsg) bool
OnAOAdd func(*ClientConn, mt.AOID, *mt.AOAdd) bool
OnAORm func(*ClientConn, mt.AOID) bool
}

// TODO:
// var aOCache map[mt.AOID]*mt.AOProps
// var aOCacheMu sync.RWMutex

var aOHandlers []*AOHandler
var aOHandlersMu sync.RWMutex

func handleAOAdd(sc *ServerConn, id mt.AOID, msg *mt.AOAdd) bool {
var handled bool

for _, handler := range aOHandlers {
if handler.OnAOAdd == nil {
continue
}
if handler.AOIDs == nil && handler.OnAOAdd(sc.clt, id, msg) {
handled = true
} else if handler.AOIDs[sc.name][id] && handler.OnAOAdd(sc.clt, id, msg) {
handled = true
}
}

return handled
}

func handleAORm(sc *ServerConn, id mt.AOID) bool {
var handled bool

for _, handler := range aOHandlers {
if handler.OnAORm == nil {
continue
}
if handler.AOIDs == nil && handler.OnAORm(sc.clt, id) {
handled = true
} else if handler.AOIDs[sc.name][id] && handler.OnAORm(sc.clt, id) {
handled = true
}
}

return handled
}

func handleAOMsg(sc *ServerConn, id mt.AOID, msg mt.AOMsg) bool {
var handled bool

for _, handler := range aOHandlers {
if handler.OnAOMsg == nil {
continue
}
if handler.AOIDs == nil && handler.OnAOMsg(sc.clt, id, msg) {
handled = true
} else if handler.AOIDs[sc.name][id] && handler.OnAOMsg(sc.clt, id, msg) {
handled = true
}
}

return handled
}

func RegisterAOHandler(h *AOHandler) {
aOHandlersMu.Lock()
defer aOHandlersMu.Unlock()

aOHandlers = append(aOHandlers, h)
}

///
/// - AOID managment
///

var LowestAOID mt.AOID = 0xA000

///
/// - Global AOIDs
///

type globalAOID struct {
used, client, server, global bool
}

var globalAOIDs = make(map[mt.AOID]globalAOID)
var globalAOIDsMu sync.RWMutex

// GetGlobalAOID returns a globally unused AOID
func GetGlobalAOID() (bool, mt.AOID) {
globalAOIDsMu.Lock()
defer globalAOIDsMu.Unlock()

notFound := true
var id mt.AOID = 0xFFFF
for notFound {
if globalAOIDs[id].used == false {
notFound = false

globalAOIDs[id] = globalAOID{used: true, global: true}
} else if id < LowestAOID {
return false, 0xFFFF
} else {
id--
}
}

return !notFound, id
}

// FreeAOID marks a id as globally unused
func FreeGlobalAOID(id mt.AOID, srv string) {
globalAOIDsMu.Lock()
defer globalAOIDsMu.Unlock()

delete(globalAOIDs, id)
}

///
/// - Server AOIDs
///

type sAOID map[mt.AOID]bool

var serverAOIDs = make(map[string]sAOID)
var serverAOIDsMu sync.RWMutex

func (sm sAOID) empty() bool {
for _, v := range sm {
if v {
return false
}
}

return true
}

// GetServerAOId returns a free mt.AOID for a server, which will be marked as used
func GetServerAOId(srv string) (bool, mt.AOID) {
globalAOIDsMu.Lock()
defer globalAOIDsMu.Unlock()

serverAOIDsMu.Lock()
defer serverAOIDsMu.Unlock()

notFound := true
var id mt.AOID = 0xFFFF
for notFound {
if globalAOIDs[id].used == false || (globalAOIDs[id].server == true && !serverAOIDs[srv][id]) {
notFound = false
if serverAOIDs[srv] == nil {
serverAOIDs[srv] = make(map[mt.AOID]bool)
}
serverAOIDs[srv][id] = true
globalAOIDs[id] = globalAOID{used: true, server: true}
} else if id < LowestAOID {
return false, 0xFFFF
} else {
id--
}
}

return !notFound, id
}

// FreeServerAOID frees a server AOID
func FreeServerAOID(srv string, id mt.AOID) {
globalAOIDsMu.Lock()
defer globalAOIDsMu.Unlock()

serverAOIDsMu.Lock()
defer serverAOIDsMu.Unlock()

delete(serverAOIDs[srv], id)
if serverAOIDs[srv].empty() {
delete(globalAOIDs, id)
}
}

///
/// - clientbound AOIDs
///

type cAOID map[mt.AOID]bool

var clientAOIDs = make(map[string]cAOID)
var clientAOIDsMu sync.RWMutex

func (ca cAOID) empty() bool {
for _, v := range ca {
if v {
return false
}
}

return true
}

// GetFreeAOID returns the next free AOID for a client
func (cc *ClientConn) GetFreeAOID() (bool, mt.AOID) {
globalAOIDsMu.Lock()
defer globalAOIDsMu.Unlock()

clientAOIDsMu.Lock()
defer clientAOIDsMu.Unlock()

name := cc.Name()

notFound := true
var id mt.AOID = 0xFFFF
for notFound {
if globalAOIDs[id].used == false || (globalAOIDs[id].client == true && !clientAOIDs[name][id]) {
notFound = false
if clientAOIDs[name] == nil {
clientAOIDs[name] = make(map[mt.AOID]bool)
}
clientAOIDs[name][id] = true
globalAOIDs[id] = globalAOID{used: true, client: true}
} else if id < LowestAOID {
return false, 0xFFFF
} else {
id--
}
}

return !notFound, id
}

// FreeAOID marks AOID as free
func (cc *ClientConn) FreeAOID(id mt.AOID) {
globalAOIDsMu.Lock()
defer globalAOIDsMu.Unlock()

clientAOIDsMu.Lock()
defer clientAOIDsMu.Unlock()

name := cc.Name()
delete(clientAOIDs[name], id)
if clientAOIDs[name].empty() {
delete(globalAOIDs, id)
}
}
76 changes: 76 additions & 0 deletions plugin_map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package proxy

import (
"sync"

"github.com/anon55555/mt"
)

type BlkDataHandler struct {
UsePos bool // if set, filters by BlkPos in Pos
Pos [3]int16 // ^ specifies BlkPos when UsePos is set
Handler func(*ClientConn, *mt.ToCltBlkData) bool
}

var blkDataHandlers []BlkDataHandler
var blkDataHandlersMu sync.RWMutex

var cacheNodes = map[string]map[mt.Content]bool{}
var cacheNodesMu sync.RWMutex

// RegisterCacheNode tells server, that nodename is suppost to be cached
func RegisterCacheNode(nodename string) {
cacheNodesMu.Lock()
defer cacheNodesMu.Unlock()

if cacheNodes[nodename] == nil {
cacheNodes[nodename] = map[mt.Content]bool{} // default value, empty map
}
}

// GetNodeId gets the nodeid of a
// If not registerd returns map[mt.Content]bool{}
func GetNodeId(nodename string) map[mt.Content]bool {
cacheNodesMu.RLock()
defer cacheNodesMu.RUnlock()

if cacheNodes[nodename] != nil {
return cacheNodes[nodename]
} else {
return nil
}
}

// addNodeId sets node id, if allready set, ignore
func addNodeId(nodename string, id mt.Content) {
cacheNodesMu.Lock()
defer cacheNodesMu.Unlock()

if cacheNodes[nodename] != nil {
cacheNodes[nodename][id] = true
}
}

// RegisterBlkDataHandler registers a BlkDataHande
func RegisterBlkDataHandler(handler BlkDataHandler) {
blkDataHandlersMu.Lock()
defer blkDataHandlersMu.Unlock()

blkDataHandlers = append(blkDataHandlers, handler)
}

func handleBlkData(cc *ClientConn, cmd *mt.ToCltBlkData) bool {
blkDataHandlersMu.RLock()
defer blkDataHandlersMu.RUnlock()

handled := false
for _, handler := range blkDataHandlers {
if !handler.UsePos && handler.Handler(cc, cmd) {
handled = true
} else if handler.Pos == cmd.Blkpos && handler.Handler(cc, cmd) {
handled = true
}
}

return handled
}
Loading