Skip to content

Commit

Permalink
refactor redundant rpc code
Browse files Browse the repository at this point in the history
  • Loading branch information
parameterized committed Oct 21, 2018
1 parent aa576c2 commit ccb3f2d
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 171 deletions.
112 changes: 45 additions & 67 deletions client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ function client.connect(ip, port)
port = tonumber(port)
client.nutClient = nut.client()
client.nutClient:addRPCs{
returnPlayer = function(self, data)
local ok, data = pcall(bitser.loads, data)
if ok then
client.startGame(data)
else
print('error decoding client rpc returnPlayer')
end
end,
chatMsg = function(self, data)
chat.addMsg(data)
end,
Expand All @@ -25,85 +17,71 @@ function client.connect(ip, port)
menu.state = 'main'
client.close()
love.mouse.setGrabbed(false)
end
}
local bitserRPCs = {
returnPlayer = function(self, data)
client.startGame(data)
end,
add = function(self, data)
local ok, data = pcall(bitser.loads, data)
if ok then
for _, v in pairs(data.projectiles) do
v.startedMoving = false
client.currentState.projectiles[v.id] = v
end
for _, v in pairs(data.entities) do
local ent = entities.client.defs[v.type]:new(v):spawn()
end
for _, v in pairs(data.lootBags) do
client.currentState.lootBags[v.id] = v
end
else
print('error decoding client rpc add')
for _, v in pairs(data.projectiles) do
v.startedMoving = false
client.currentState.projectiles[v.id] = v
end
for _, v in pairs(data.entities) do
local ent = entities.client.defs[v.type]:new(v):spawn()
end
for _, v in pairs(data.lootBags) do
client.currentState.lootBags[v.id] = v
end
end,
remove = function(self, data)
local ok, data = pcall(bitser.loads, data)
if ok then
for _, id in pairs(data.projectiles) do
client.currentState.projectiles[id] = nil
end
for _, id in pairs(data.entities) do
local ent = client.currentState.entities[id]
if ent then ent:destroy() end
client.currentState.entities[id] = nil
end
for _, id in pairs(data.lootBags) do
client.currentState.lootBags[id] = nil
end
else
print('error decoding client rpc remove')
for _, id in pairs(data.projectiles) do
client.currentState.projectiles[id] = nil
end
for _, id in pairs(data.entities) do
local ent = client.currentState.entities[id]
if ent then ent:destroy() end
client.currentState.entities[id] = nil
end
for _, id in pairs(data.lootBags) do
client.currentState.lootBags[id] = nil
end
end,
stateUpdate = function(self, data)
local ok, data = pcall(bitser.loads, data)
if ok then
client.serverTime = data.time
-- todo: delete old states (or make replay feature)
-- todo: multiple states in update -
-- - 20fps update -> 60fps replay, (3 states per update)
table.insert(client.states, data)
--[[
if #client.states == 2 then
client.stateTime = client.states[1].time
end
]]
else
print('error decoding client rpc stateUpdate')
client.serverTime = data.time
-- todo: delete old states (or make replay feature)
-- todo: multiple states in update -
-- - 20fps update -> 60fps replay, (3 states per update)
table.insert(client.states, data)
--[[
if #client.states == 2 then
client.stateTime = client.states[1].time
end
]]
end,
returnItem = function(self, data)
local ok, data = pcall(bitser.loads, data)
if ok then
items.client.container[data.id] = data.item
items.client.requested[data.id] = nil
else
print('error decoding client rpc returnItem')
end
items.client.container[data.id] = data.item
items.client.requested[data.id] = nil
end,
bagUpdate = function(self, data)
local ok, data = pcall(bitser.loads, data)
if ok then
client.currentState.lootBags[data.id] = data
else
print('error decoding client rpc bagUpdate')
end
client.currentState.lootBags[data.id] = data
end,
setWorldChunk = function(self, data)
world.client.setChunk(data.x, data.y, data.chunk)
end
}
for k, v in pairs(bitserRPCs) do
bitserRPCs[k] = function(self, data)
local ok, data = pcall(bitser.loads, data)
if ok then
world.client.setChunk(data.x, data.y, data.chunk)
v(self, data)
else
print('error decoding client rpc setWorldChunk')
print('error decoding client rpc ' .. k)
end
end
}
end
client.nutClient:addRPCs(bitserRPCs)
client.nutClient:addUpdate(function(self)
if gameState == 'playing' then
self:sendRPC('setPlayer', bitser.dumps(playerController.player:serialize()))
Expand Down
191 changes: 87 additions & 104 deletions server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,138 +43,121 @@ function server.start(port, singleplayer)
chatMsg = function(self, data, clientId)
local pname = server.currentState.players[clientId].name
self:sendRPC('chatMsg', string.format('%s: %s', pname, data))
end,
end
}
local bitserRPCs = {
setPlayer = function(self, data, clientId)
local ok, data = pcall(bitser.loads, data)
if ok then
if not server.currentState.players[clientId] then
print('attempt to setPlayer on non-existent player')
return
end
server.currentState.players[clientId]:setState(data)
else
print('error decoding server rpc setPlayer')
if not server.currentState.players[clientId] then
print('attempt to setPlayer on non-existent player')
return
end
server.currentState.players[clientId]:setState(data)
end,
spawnProjectile = function(self, data, clientId)
local ok, data = pcall(bitser.loads, data)
if ok then
local playerId = server.currentState.players[clientId].id
data.playerId = playerId
projectiles.server.spawn(data)
else
print('error decoding server rpc spawnBullet')
end
local playerId = server.currentState.players[clientId].id
data.playerId = playerId
projectiles.server.spawn(data)
end,
getItem = function(self, data, clientId)
local ok, data = pcall(bitser.loads, data)
if ok then
local res = {id=data.id, item=items.server.getItem(data.id)}
server.nutServer:sendRPC('returnItem', bitser.dumps(res))
else
print('error decoding server rpc getItem')
end
local res = {id=data.id, item=items.server.getItem(data.id)}
server.nutServer:sendRPC('returnItem', bitser.dumps(res))
end,
moveItem = function(self, data, clientId)
local ok, data = pcall(bitser.loads, data)
if ok then
-- todo: validation
local p = server.currentState.players[clientId]
local bagFrom = server.currentState.lootBags[data.from.bagId]
if data.from.bagId == 'inventory' then
bagFrom = p.inventory
end
local bagTo = server.currentState.lootBags[data.to.bagId]
if data.to.bagId == 'inventory' then
bagTo = p.inventory
end
if bagFrom and bagTo then
if bagFrom.items[data.from.slotId] then
local temp = bagTo.items[data.to.slotId]
bagTo.items[data.to.slotId] = bagFrom.items[data.from.slotId]
bagFrom.items[data.from.slotId] = temp
-- remove bag if empty
if bagFrom.id ~= 'inventory' then
local empty = true
for _, v in pairs(bagFrom.items) do
if v ~= nil then
empty = false
break
end
end
if empty then
lootBags.server.destroy(bagFrom.id)
-- todo: validation
local p = server.currentState.players[clientId]
local bagFrom = server.currentState.lootBags[data.from.bagId]
if data.from.bagId == 'inventory' then
bagFrom = p.inventory
end
local bagTo = server.currentState.lootBags[data.to.bagId]
if data.to.bagId == 'inventory' then
bagTo = p.inventory
end
if bagFrom and bagTo then
if bagFrom.items[data.from.slotId] then
local temp = bagTo.items[data.to.slotId]
bagTo.items[data.to.slotId] = bagFrom.items[data.from.slotId]
bagFrom.items[data.from.slotId] = temp
-- remove bag if empty
if bagFrom.id ~= 'inventory' then
local empty = true
for _, v in pairs(bagFrom.items) do
if v ~= nil then
empty = false
break
end
end
-- inventory sent in player update
if data.from.bagId ~= 'inventory' then
server.nutServer:sendRPC('bagUpdate', bitser.dumps(bagFrom))
end
if data.to.bagId ~= 'inventory' then
server.nutServer:sendRPC('bagUpdate', bitser.dumps(bagTo))
if empty then
lootBags.server.destroy(bagFrom.id)
end
end
-- inventory sent in player update
if data.from.bagId ~= 'inventory' then
server.nutServer:sendRPC('bagUpdate', bitser.dumps(bagFrom))
end
if data.to.bagId ~= 'inventory' then
server.nutServer:sendRPC('bagUpdate', bitser.dumps(bagTo))
end
end
else
print('error decoding server rpc moveItem')
end
end,
dropItem = function(self, data, clientId)
local ok, data = pcall(bitser.loads, data)
if ok then
local p = server.currentState.players[clientId]
local item = p.inventory.items[data.slotId]
if item then
local itemDropped = false
local bags = {}
for _, bag in pairs(lootBags.server.container) do
table.insert(bags, bag)
end
local sortedBags = isort(bags, function(a, b)
local da = (a.x - p.x)^2 + (a.y - p.y)^2
local db = (b.x - p.x)^2 + (b.y - p.y)^2
return da < db
end)
for _, bag in ipairs(sortedBags) do
local dist = math.sqrt((bag.x - p.x)^2 + (bag.y - p.y)^2)
if dist < lootBags.client.openRange then
for bagSlotId, _ in ipairs(lootBags.client.slots) do
if bag.items[bagSlotId] == nil then
bag.items[bagSlotId] = item
server.nutServer:sendRPC('bagUpdate', bitser.dumps(bag))
itemDropped = true
break
end
local p = server.currentState.players[clientId]
local item = p.inventory.items[data.slotId]
if item then
local itemDropped = false
local bags = {}
for _, bag in pairs(lootBags.server.container) do
table.insert(bags, bag)
end
local sortedBags = isort(bags, function(a, b)
local da = (a.x - p.x)^2 + (a.y - p.y)^2
local db = (b.x - p.x)^2 + (b.y - p.y)^2
return da < db
end)
for _, bag in ipairs(sortedBags) do
local dist = math.sqrt((bag.x - p.x)^2 + (bag.y - p.y)^2)
if dist < lootBags.client.openRange then
for bagSlotId, _ in ipairs(lootBags.client.slots) do
if bag.items[bagSlotId] == nil then
bag.items[bagSlotId] = item
server.nutServer:sendRPC('bagUpdate', bitser.dumps(bag))
itemDropped = true
break
end
end
if itemDropped then break end
end
if not itemDropped then
lootBags.server.spawn{
x = p.x, y = p.y,
items = {item},
life = 30
}
itemDropped = true
end
p.inventory.items[data.slotId] = nil
-- inventory sent in player update
if itemDropped then break end
end
else
print('error decoding server rpc dropItem')
if not itemDropped then
lootBags.server.spawn{
x = p.x, y = p.y,
items = {item},
life = 30
}
itemDropped = true
end
p.inventory.items[data.slotId] = nil
-- inventory sent in player update
end
end,
getWorldChunk = function(self, data, clientId)
local chunk = world.server.getChunk(data.x, data.y)
local res = {x=data.x, y=data.y, chunk=chunk}
server.nutServer:sendRPC('setWorldChunk', bitser.dumps(res), clientId)
end
}
for k, v in pairs(bitserRPCs) do
bitserRPCs[k] = function(self, data, clientId)
local ok, data = pcall(bitser.loads, data)
if ok then
local chunk = world.server.getChunk(data.x, data.y)
local res = {x=data.x, y=data.y, chunk=chunk}
server.nutServer:sendRPC('setWorldChunk', bitser.dumps(res), clientId)
v(self, data, clientId)
else
print('error decoding server rpc getWorldChunk')
print('error decoding server rpc ' .. k)
end
end
}
end
server.nutServer:addRPCs(bitserRPCs)
server.nutServer:addUpdate(function(self)
local addStr = bitser.dumps(server.added)
if addStr ~= bitser.dumps(server.newState()) then
Expand Down

0 comments on commit ccb3f2d

Please sign in to comment.