Compare commits

...

5 Commits

18 changed files with 445 additions and 440 deletions

29
FixMime
View File

@ -1,16 +1,39 @@
#!sh #!sh
#adjust the next line... not sure how to figure this out from a shellscript, sorry :) # This mechanism is fairly unreliable, but it is the only "okay" way currently :/
cd ~/proj/poppy-client-loeve # realpath is also not part of any POSIX standard
cd $(dirname $(realpath "$0"))
if test $? -eq 1; then if test $? -eq 1; then
alert --stop "cant figure out where this script is" "Ill adjust it!" alert --stop "cant figure out where this script is" "Ill adjust it!"
exit exit
fi fi
touch log
for i in lua/*.lua; do for i in lua/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i; addattr -t mime BEOS:TYPE text/x-source-code $i;
done done
for i in server/*.lua; do for i in server/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i; addattr -t mime BEOS:TYPE text/x-source-code $i;
done done
for i in server/commands/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
for i in server/unpriviliged_commands/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
for i in shared/*.lua; do
echo "$i" >> log
addattr -t mime BEOS:TYPE text/x-source-code $i;
done
alert --info "Fixed mime types
$(cat log)"
rm log

View File

@ -95,7 +95,7 @@ end
function camera.setplayer() function camera.setplayer()
if camera.target == 0 then return end if camera.target == 0 then return end
player = players[camera.target] player = participants[camera.target]
camera.offsetclamp() camera.offsetclamp()
local perfectx = math.floor(player.x * -1) + ((window.x -300)/2 -((player.avatar:getWidth() /2) / scale)) / scale + camera.offset.x local perfectx = math.floor(player.x * -1) + ((window.x -300)/2 -((player.avatar:getWidth() /2) / scale)) / scale + camera.offset.x
local perfecty = math.floor(player.y * -1) + (window.y/2 -((player.avatar:getHeight() /2) / scale)) / scale + camera.offset.y local perfecty = math.floor(player.y * -1) + (window.y/2 -((player.avatar:getHeight() /2) / scale)) / scale + camera.offset.y
@ -107,7 +107,7 @@ end
function camera.update() function camera.update()
if camera.target == 0 then return end if camera.target == 0 then return end
player = players[camera.target] player = participants[camera.target]
--[[ Update camera to track player ]]-- --[[ Update camera to track player ]]--
local perfectx = math.floor(player.x * -1) + ((window.x -300)/2 -(player.avatar:getWidth() /2)) / scale + camera.offset.x local perfectx = math.floor(player.x * -1) + ((window.x -300)/2 -(player.avatar:getWidth() /2)) / scale + camera.offset.x
local perfecty = math.floor(player.y * -1) + (window.y/2 -(player.avatar:getHeight() /2)) / scale + camera.offset.y local perfecty = math.floor(player.y * -1) + (window.y/2 -(player.avatar:getHeight() /2)) / scale + camera.offset.y

View File

@ -3,114 +3,91 @@ local player = require("lua.player")
local utils = require("shared.utils") local utils = require("shared.utils")
local fonts = require("shared.fonts") local fonts = require("shared.fonts")
local commands = {} return function(commands)
local sharedCommands = require("shared.commands") commands.init = function(clientID, args)
local nickname, args = utils.nextStringRecord(args)
local avatarEncoded, args = utils.nextStringRecord(args)
local worldID, args = utils.nextStringRecord(args)
local x, args = utils.nextIntRecord(args)
local y = tonumber(args)
local avatar = love.data.decode("string", "base64", avatarEncoded)
print("Connected as " .. clientID .. " with name " .. nickname)
print("New world is " .. worldID .. " Size is [" .. x .. "|" .. y .. "]")
participants[clientID] = player.newPlayer({name = nickname, avatar = levelloop.avatars[avatar].image})
camera.target = clientID
_G.clientID = clientID
commands.commandsInit = sharedCommands.commandsInit local world = { id = worldID, x = x, y = y }
levelloop.loadworld(world)
commands.commandsWorldInit = sharedCommands.commandsWorldInit
commands.init = function(clientID, args)
local nickname, args = utils.nextStringRecord(args)
local avatarEncoded, args = utils.nextStringRecord(args)
local worldID, args = utils.nextStringRecord(args)
local x, args = utils.nextIntRecord(args)
local y = tonumber(args)
local avatar = love.data.decode("string", "base64", avatarEncoded)
print("Connected as " .. clientID .. " with name " .. nickname)
print("New world is " .. worldID .. " Size is [" .. x .. "|" .. y .. "]")
players[clientID] = player.newPlayer({name = nickname, avatar = gameloop.avatars[avatar].image})
camera.target = clientID
_G.clientID = clientID
local world = { id = worldID, x = x, y = y }
gameloop.loadworld(world)
end
commands.ping = function(clientID)
gameloop.networkSend("pong")
end
commands.saveWorld = function(clientID, args)
local status, savename = utils.nextStringRecord(args)
if status == "failed" then
ui.addChatEntry("SERVER", "Failed to save world!")
elseif status == "sucess" then
ui.addChatEntry("SERVER", "saved world. " .. savename)
end end
end
commands.playerJoin = function(clientID, args) commands.ping = function(clientID)
local nickname, avatarEncoded = utils.nextStringRecord(args) levelloop.networkSend("pong")
avatarHash = love.data.decode("string", "base64", avatarEncoded)
ui.addChatEntry("", nickname .. " Joined the game")
local avatar = { image = love.graphics.newImage("textures/player/nephele/fallback.png") }
if gameloop.avatars[avatarHash] then
avatar = gameloop.avatars[avatarHash]
end end
players[clientID] = player.newPlayer({name = nickname, avatar = avatar.image})
players[clientID].label = love.graphics.newText(fonts.smallFont, nickname)
end
commands.playerLeave = function(clientID) commands.saveWorld = function(clientID, args)
if players[clientID] then local status, savename = utils.nextStringRecord(args)
local name = players[clientID].name if status == "failed" then
ui.addChatEntry("", name .. " Left the game") ui.addChatEntry("SERVER", "Failed to save world!")
players[clientID] = nil elseif status == "sucess" then
end ui.addChatEntry("SERVER", "saved world. " .. savename)
end
commands.deletePhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.remove_solid(utils.getIntRecords(4, args))
end
commands.drawPhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.draw_solid(utils.getIntRecords(4, args))
end
commands.chatMessage = function(clientID, args)
local name
if clientID == "0" then
name = ""
else
if players[clientID] and players[clientID].name then
name = players[clientID].name
else
name = "UNKNOWN?"
end end
end end
ui.addChatEntry(name, args)
commands.playerJoin = function(clientID, args)
local nickname, avatarEncoded = utils.nextStringRecord(args)
avatarHash = love.data.decode("string", "base64", avatarEncoded)
ui.addChatEntry("", nickname .. " Joined the game")
local avatar = { image = love.graphics.newImage("textures/player/nephele/fallback.png") }
if levelloop.avatars[avatarHash] then
avatar = levelloop.avatars[avatarHash]
end
participants[clientID] = player.newPlayer({name = nickname, avatar = avatar.image})
participants[clientID].label = love.graphics.newText(fonts.smallFont, nickname)
end
commands.playerLeave = function(clientID)
if participants[clientID] then
local name = participants[clientID].name
ui.addChatEntry("", name .. " Left the game")
participants[clientID] = nil
end
end
commands.deletePhysics = function(clientID, args)
if clientID == camera.target then return end
if not participants[clientID] then return end
physics.remove_solid(utils.getIntRecords(4, args))
end
commands.drawPhysics = function(clientID, args)
if clientID == camera.target then return end
if not participants[clientID] then return end
physics.draw_solid(utils.getIntRecords(4, args))
end
commands.chatMessage = function(clientID, args)
local name
if clientID == "0" then
name = ""
else
if participants[clientID] and participants[clientID].name then
name = participants[clientID].name
else
name = "UNKNOWN?"
end
end
ui.addChatEntry(name, args)
end
commands.clearCanvas = function(clientID)
drawing.clearAllCanvases()
end
end end
commands.deleteTexture = sharedCommands.deleteTexture
commands.drawTexture = sharedCommands.drawTexture
commands.moveUpdate = sharedCommands.moveUpdate
commands.moveFlying = sharedCommands.moveFlying
commands.clearCanvas = function(clientID)
drawing.clearAllCanvases()
end
commands.fillCanvas = function(clientID, args)
local layer, hash = utils.nextStringRecord(args)
hash = love.data.decode("string", "base64", hash)
drawing.fillCanvas(layer, hash)
end
return commands

View File

@ -6,58 +6,64 @@ end
local utils = require("shared.utils") local utils = require("shared.utils")
function drawing.clearAllCanvases() function drawing.clearAllCanvases()
love.graphics.setCanvas(gameloop.Canvas.fg) love.graphics.setCanvas(levelloop.Canvas.fg)
love.graphics.clear() love.graphics.clear()
love.graphics.setCanvas(gameloop.Canvas.bg) love.graphics.setCanvas(levelloop.Canvas.bg)
love.graphics.clear() love.graphics.clear()
love.graphics.setCanvas(gameloop.Canvas.dbg) love.graphics.setCanvas(levelloop.Canvas.dbg)
love.graphics.clear() love.graphics.clear()
love.graphics.setCanvas() love.graphics.setCanvas()
gameloop.Canvas.physics = {} levelloop.Canvas.physics = {}
end end
function drawing.clearAllCanvasesNetwork() function drawing.clearAllCanvasesNetwork()
gameloop.networkSend("clearCanvas") levelloop.networkSend("clearCanvas")
drawing.clearAllCanvases() drawing.clearAllCanvases()
end end
function drawing.fillCanvas(layer, hash) function drawing.fillCanvas(layer, hash, color)
love.graphics.setCanvas(gameloop.Canvas[layer]) love.graphics.setCanvas(levelloop.Canvas[layer])
love.graphics.clear() love.graphics.clear()
for x = 0, gameloop.world.x -gameloop.textures[hash].image:getPixelWidth(), utils.color_push()
gameloop.textures[hash].image:getPixelWidth() do love.graphics.setColor(color)
for y = 0, gameloop.world.y -gameloop.textures[hash].image:getPixelHeight(), for x = 0, levelloop.world.x -levelloop.textures[hash].image:getPixelWidth(),
gameloop.textures[hash].image:getPixelHeight() do levelloop.textures[hash].image:getPixelWidth() do
love.graphics.draw(gameloop.textures[hash].image, x, y) for y = 0, levelloop.world.y -levelloop.textures[hash].image:getPixelHeight(),
levelloop.textures[hash].image:getPixelHeight() do
love.graphics.draw(levelloop.textures[hash].image, x, y)
end end
end end
utils.color_pop()
love.graphics.setCanvas() love.graphics.setCanvas()
end end
function drawing.fillCanvasNetwork(layer, hash) function drawing.fillCanvasNetwork(layer, hash, color)
gameloop.networkSend(utils.unit("fillCanvas", layer, love.data.encode("string", "base64", hash))) levelloop.networkSend(utils.unit("fillCanvas", layer,
drawing.fillCanvas(layer, hash) love.data.encode("string", "base64", hash),
color[1], color[2], color[3], color[4] or "1"))
drawing.fillCanvas(layer, hash, color)
end end
function drawing.keyreleased(key, _) function drawing.keyreleased(key, _)
assert(drawing.color)
if key == "c" then if key == "c" then
drawing.clearAllCanvasesNetwork() drawing.clearAllCanvasesNetwork()
end end
if key == "f" then if key == "f" then
drawing.fillCanvasNetwork("fg", drawing.cursorHash) drawing.fillCanvasNetwork("fg", drawing.cursorHash, drawing.color)
end end
if key == "b" then if key == "b" then
drawing.fillCanvasNetwork("bg", drawing.cursorHash) drawing.fillCanvasNetwork("bg", drawing.cursorHash, drawing.color)
end end
end end
local drawmouse = {} local drawmouse = {}
function drawing.input(dt) function drawing.input(dt)
local textures = gameloop.textures local textures = levelloop.textures
local cursor = drawing.cursor local cursor = drawing.cursor
if not cursor or not cursor.data then return end if not cursor or not cursor.data then return end
assert(cursor, "Failed to find cursor") assert(cursor, "Failed to find cursor")
@ -74,8 +80,8 @@ function drawing.input(dt)
end end
mousex = mousex / scale - view.x mousex = mousex / scale - view.x
mousey = mousey / scale - view.y mousey = mousey / scale - view.y
if mousex > gameloop.world.x or if mousex > levelloop.world.x or
mousey > gameloop.world.y or mousey > levelloop.world.y or
mousex < 0 or mousex < 0 or
mousey < 0 then mousey < 0 then
return return
@ -101,9 +107,9 @@ function drawing.input(dt)
local ctrlDown = love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl") local ctrlDown = love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl")
if ctrlDown then if ctrlDown then
love.graphics.setCanvas(gameloop.Canvas.bg) love.graphics.setCanvas(levelloop.Canvas.bg)
else else
love.graphics.setCanvas(gameloop.Canvas.fg) love.graphics.setCanvas(levelloop.Canvas.fg)
end end
if love.mouse.isDown(1) then -- only delete if love.mouse.isDown(1) then -- only delete
@ -156,7 +162,7 @@ function drawing.draw_texture(hash, x, y, layer, color)
if not color[4] then color[4] = 1 end if not color[4] then color[4] = 1 end
local last = drawing.lastTexture local last = drawing.lastTexture
if hash ~= last.hash or x ~= last.x or y ~= last.y or layer ~= last.layer then if hash ~= last.hash or x ~= last.x or y ~= last.y or layer ~= last.layer then
gameloop.networkSend(utils.unit("drawTexture", x, y, levelloop.networkSend(utils.unit("drawTexture", x, y,
layer, love.data.encode("string", "base64", hash), color[1], color[2], color[3], color[4])) layer, love.data.encode("string", "base64", hash), color[1], color[2], color[3], color[4]))
end end
last.hash, last.x, last.y, last.layer = hash, x, y, layer last.hash, last.x, last.y, last.layer = hash, x, y, layer
@ -169,7 +175,7 @@ function drawing.del_texture(x, y, width, height, layer)
local last = drawing.lastTextureDel local last = drawing.lastTextureDel
if x ~= last.x or y ~= last.y or width ~= last.width if x ~= last.x or y ~= last.y or width ~= last.width
or height ~= last.height or layer ~= last.layer then or height ~= last.height or layer ~= last.layer then
gameloop.networkSend(utils.unit("deleteTexture", x, y, width, height, layer)) levelloop.networkSend(utils.unit("deleteTexture", x, y, width, height, layer))
last.x, last.y, last.width, last.height, last.layer = x, y, width, height, layer last.x, last.y, last.width, last.height, last.layer = x, y, width, height, layer
end end
end end
@ -178,7 +184,7 @@ end
local lastDWP = { x = 0, y = 0, width = 0, height = 0} local lastDWP = { x = 0, y = 0, width = 0, height = 0}
function drawing.draw_solid(x, y, width, height) function drawing.draw_solid(x, y, width, height)
if x ~= lastDWP.x or y ~= lastDWP.y or width ~= lastDWP.width or height ~= lastDWP.height then if x ~= lastDWP.x or y ~= lastDWP.y or width ~= lastDWP.width or height ~= lastDWP.height then
gameloop.networkSend(utils.unit("drawPhysics", x, y, width, height)) levelloop.networkSend(utils.unit("drawPhysics", x, y, width, height))
physics.draw_solid(x, y, width, height) physics.draw_solid(x, y, width, height)
lastDWP.x, lastDWP.y, lastDWP.width, lastDWP.height = x, y, width, height lastDWP.x, lastDWP.y, lastDWP.width, lastDWP.height = x, y, width, height
end end
@ -188,7 +194,7 @@ end
local lastRMP = { x = 0, y = 0, width = 0, height = 0} local lastRMP = { x = 0, y = 0, width = 0, height = 0}
function drawing.remove_solid(x, y, width, height) function drawing.remove_solid(x, y, width, height)
if x ~= lastRMP.x or y ~= lastRMP.y or width ~= lastRMP.width or height ~= lastRMP.height then if x ~= lastRMP.x or y ~= lastRMP.y or width ~= lastRMP.width or height ~= lastRMP.height then
gameloop.networkSend(utils.unit("deletePhysics", x, y, width, height)) levelloop.networkSend(utils.unit("deletePhysics", x, y, width, height))
physics.remove_solid(x, y, width, height) physics.remove_solid(x, y, width, height)
lastRMP.x, lastRMP.y, lastRMP.width, lastRMP.height = x, y, width, height lastRMP.x, lastRMP.y, lastRMP.width, lastRMP.height = x, y, width, height
end end

View File

@ -1,8 +1,12 @@
gameloop = {} levelloop = {}
gameloop.world = nil levelloop.CLIENT = true
gameloop.textures = {} levelloop.world = nil
gameloop.avatars = {} levelloop.textures = {}
commands = require("lua.commands") levelloop.avatars = {}
commands = {}
require("lua.commands")(commands)
require("shared.commands")(commands)
local socket = require "socket" local socket = require "socket"
local utils = require("shared.utils") local utils = require("shared.utils")
@ -12,8 +16,8 @@ local errorHandler = require("shared.error")
local rpc = require("server.rpc") local rpc = require("server.rpc")
local constants = require("server.constants") local constants = require("server.constants")
gameloop.nwChecklist = {} levelloop.nwChecklist = {}
gameloop.Canvas = {} levelloop.Canvas = {}
local count = 1 local count = 1
local function normalDraw() local function normalDraw()
if count == 1 then print("use canvas!") count = 2 end if count == 1 then print("use canvas!") count = 2 end
@ -23,14 +27,14 @@ local function normalDraw()
if drawBackground then if drawBackground then
utils.color_push() utils.color_push()
love.graphics.setColor(0.05, 0.05, 0.05) love.graphics.setColor(0.05, 0.05, 0.05)
love.graphics.rectangle("fill", math.floor(view.x) * scale, math.floor(view.y) * scale, gameloop.world.x * scale, gameloop.world.y * scale) love.graphics.rectangle("fill", math.floor(view.x) * scale, math.floor(view.y) * scale, levelloop.world.x * scale, levelloop.world.y * scale)
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(gameloop.Canvas.bg, layerTransform) love.graphics.draw(levelloop.Canvas.bg, layerTransform)
utils.color_pop() utils.color_pop()
end end
-- draw player -- draw player
for i, player in pairs(players) do for i, player in pairs(participants) do
local playerTransform = love.math.newTransform( local playerTransform = love.math.newTransform(
math.floor(player.x) * scale + math.floor(view.x) * scale, math.floor(player.x) * scale + math.floor(view.x) * scale,
math.floor(player.y) * scale + math.floor(view.y) * scale, math.floor(player.y) * scale + math.floor(view.y) * scale,
@ -51,7 +55,7 @@ local function normalDraw()
end end
-- Draw foreground -- Draw foreground
love.graphics.draw(gameloop.Canvas.fg, layerTransform) love.graphics.draw(levelloop.Canvas.fg, layerTransform)
-- Draw UI -- Draw UI
love.graphics.draw(ui.buffer) love.graphics.draw(ui.buffer)
@ -62,10 +66,10 @@ local function debugDraw()
normalDraw() normalDraw()
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale) local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
love.graphics.draw(gameloop.Canvas.dbg, layerTransform) love.graphics.draw(levelloop.Canvas.dbg, layerTransform)
love.graphics.draw(gameloop.Canvas.dbg2, layerTransform) love.graphics.draw(levelloop.Canvas.dbg2, layerTransform)
love.graphics.setCanvas(gameloop.Canvas.dbg2) love.graphics.setCanvas(levelloop.Canvas.dbg2)
love.graphics.clear() love.graphics.clear()
love.graphics.setCanvas() love.graphics.setCanvas()
end end
@ -74,7 +78,7 @@ end
local function normalNetworkSend(args) local function normalNetworkSend(args)
if clientID == "0" then print("Invalid clientID?") end if clientID == "0" then print("Invalid clientID?") end
local request = constants.protocolVersion ..US.. clientID ..US.. args local request = constants.protocolVersion ..US.. clientID ..US.. args
gameloop.client:send(request) levelloop.client:send(request)
end end
@ -82,14 +86,14 @@ local function debugNetworkSend(args)
assert(clientID ~= 0) assert(clientID ~= 0)
local request = constants.protocolVersion ..constants.US.. clientID ..constants.US.. args local request = constants.protocolVersion ..constants.US.. clientID ..constants.US.. args
print("=> " .. utils.pprint(request)) print("=> " .. utils.pprint(request))
gameloop.client:send(request) levelloop.client:send(request)
end end
function normalNetworkSync() function normalNetworkSync()
local message, errorString = nil, false local message, errorString = nil, false
while not errorString do while not errorString do
local message, errorString = gameloop.client:receive() local message, errorString = levelloop.client:receive()
if not message then if not message then
if errorString == "timeout" then return else if errorString == "timeout" then return else
error(errorString) error(errorString)
@ -109,7 +113,7 @@ end
function debugNetworkSync() function debugNetworkSync()
local message, errorString = nil, false local message, errorString = nil, false
while not errorString do while not errorString do
local message, errorString = gameloop.client:receive() local message, errorString = levelloop.client:receive()
if message then print("<= " .. utils.pprint(message)) end if message then print("<= " .. utils.pprint(message)) end
if not message then if not message then
if errorString == "timeout" then return else if errorString == "timeout" then return else
@ -129,17 +133,17 @@ end
local function errorhandlerNetwork(msg) local function errorhandlerNetwork(msg)
gameloop.networkSend(unit("playerLeave")) levelloop.networkSend(unit("playerLeave"))
return errorHandler.redscreen(msg) return errorHandler.redscreen(msg)
end end
function gameloop.mousepressed(mousex, mousey) function levelloop.mousepressed(mousex, mousey)
ui.mousepressed(mousex, mousey) ui.mousepressed(mousex, mousey)
end end
function gameloop.loadAvatars() function levelloop.loadAvatars()
local container = {} local container = {}
local entries = love.filesystem.getDirectoryItems("textures/player") local entries = love.filesystem.getDirectoryItems("textures/player")
if #entries == 0 then return error("no avatars found") end if #entries == 0 then return error("no avatars found") end
@ -157,17 +161,17 @@ function gameloop.loadAvatars()
end end
end end
end end
gameloop.avatars = container levelloop.avatars = container
end end
function gameloop.init(server, nickname, avatarHash) function levelloop.init(server, nickname, avatarHash)
local US = constants.US local US = constants.US
love.errorhandler = errorHandler.redscreen love.errorhandler = errorHandler.redscreen
assert(server, "Gameloop called without server to connect to?") assert(server, "levelloop called without server to connect to?")
assert(nickname, "Gameloop called without nickname?") assert(nickname, "levelloop called without nickname?")
assert(avatarHash, "Gameloop called without avatar?") assert(avatarHash, "levelloop called without avatar?")
gameloop.server = server levelloop.server = server
scale = 1 scale = 1
@ -182,7 +186,7 @@ function gameloop.init(server, nickname, avatarHash)
window = {} window = {}
window.x, window.y = love.graphics.getDimensions() window.x, window.y = love.graphics.getDimensions()
players = {} participants = {}
textures = {} textures = {}
view = {} view = {}
@ -192,30 +196,29 @@ function gameloop.init(server, nickname, avatarHash)
-- Must be done now because it has to be ready before "init" returns from the server -- Must be done now because it has to be ready before "init" returns from the server
-- which is /before/ the game world is loaded -- which is /before/ the game world is loaded
gameloop.loadAvatars() levelloop.loadAvatars()
commands.commandsInit()
gameloop.client = socket.udp() levelloop.client = socket.udp()
gameloop.client:setpeername(server.adress, server.port) levelloop.client:setpeername(server.adress, server.port)
gameloop.client:settimeout(0) levelloop.client:settimeout(0)
print("Socketnname: " .. gameloop.client:getsockname()) print("Socketnname: " .. levelloop.client:getsockname())
print("Connecting to [" .. server.adress .."]:" .. server.port) print("Connecting to [" .. server.adress .."]:" .. server.port)
local request = constants.protocolVersion ..US.. "0" ..US.. utils.unit("init", nickname, love.data.encode("string", "base64", avatarHash)) local request = constants.protocolVersion ..US.. "0" ..US.. utils.unit("init", nickname, love.data.encode("string", "base64", avatarHash))
gameloop.client:send(request) levelloop.client:send(request)
if NETWORK_DEBUG then print("=> " .. utils.pprint(request)) end if NETWORK_DEBUG then print("=> " .. utils.pprint(request)) end
if not NETWORK_DEBUG then if not NETWORK_DEBUG then
gameloop.networkSend = normalNetworkSend levelloop.networkSend = normalNetworkSend
gameloop.networkSync = normalNetworkSync levelloop.networkSync = normalNetworkSync
else else
gameloop.networkSend = debugNetworkSend levelloop.networkSend = debugNetworkSend
gameloop.networkSync = debugNetworkSync levelloop.networkSync = debugNetworkSync
end end
love.update = function(dt) love.update = function(dt)
gameloop.networkSync(dt) levelloop.networkSync(dt)
love.timer.sleep((1/60) -dt) love.timer.sleep((1/60) -dt)
end end
@ -236,8 +239,8 @@ function gameloop.init(server, nickname, avatarHash)
end end
function gameloop.normalVisible(dt) function levelloop.normalVisible(dt)
gameloop.networkSync(dt) levelloop.networkSync(dt)
camera.input(dt) camera.input(dt)
physics.input(dt) physics.input(dt)
drawing.input(dt) drawing.input(dt)
@ -247,20 +250,20 @@ function gameloop.normalVisible(dt)
end end
function gameloop.reducedVisible(dt) function levelloop.reducedVisible(dt)
gameloop.networkSync(dt) levelloop.networkSync(dt)
physics.update(dt) physics.update(dt)
love.timer.sleep((1/60) -dt) love.timer.sleep((1/60) -dt)
end end
function gameloop.keypressed(key, _) function levelloop.keypressed(key, _)
physics.keypressed(key, _) physics.keypressed(key, _)
camera.keypressed(key, _) camera.keypressed(key, _)
end end
function gameloop.keyreleased(key, _) function levelloop.keyreleased(key, _)
if key == "r" then if key == "r" then
drawBackground = not drawBackground drawBackground = not drawBackground
end end
@ -270,36 +273,35 @@ function gameloop.keyreleased(key, _)
end end
function gameloop.loadworld(world) function levelloop.loadworld(world)
-- Game connected! -- Game connected!
--love.errorhandler = errorhandlerNetwork --love.errorhandler = errorhandlerNetwork
print("make canvas!") print("make canvas!")
gameloop.Canvas.fg = love.graphics.newCanvas(world.x, world.y) levelloop.Canvas.fg = love.graphics.newCanvas(world.x, world.y)
gameloop.Canvas.bg = love.graphics.newCanvas(world.x, world.y) levelloop.Canvas.bg = love.graphics.newCanvas(world.x, world.y)
if PHYSICS_DEBUG then if PHYSICS_DEBUG then
gameloop.Canvas.dbg = love.graphics.newCanvas(world.x, world.y) levelloop.Canvas.dbg = love.graphics.newCanvas(world.x, world.y)
gameloop.Canvas.dbg2 = love.graphics.newCanvas(world.x, world.y) levelloop.Canvas.dbg2 = love.graphics.newCanvas(world.x, world.y)
end end
gameloop.Canvas.physics = {} levelloop.Canvas.physics = {}
commands.commandsWorldInit()
ui.init() ui.init()
drawing.init() drawing.init()
love.update = gameloop.normalVisible love.update = levelloop.normalVisible
love.visible = function(visible) love.visible = function(visible)
if visible then if visible then
love.update = gameloop.normalVisible love.update = levelloop.normalVisible
else else
love.update = gameloop.reducedVisible love.update = levelloop.reducedVisible
end end
end end
drawBackground = true drawBackground = true
love.keyreleased = gameloop.keyreleased love.keyreleased = levelloop.keyreleased
love.keypressed = gameloop.keypressed love.keypressed = levelloop.keypressed
love.mousepressed = gameloop.mousepressed love.mousepressed = levelloop.mousepressed
if not PHYSICS_DEBUG then if not PHYSICS_DEBUG then
love.draw = normalDraw love.draw = normalDraw
else else
@ -315,8 +317,8 @@ function gameloop.loadworld(world)
end end
love.quit = function() love.quit = function()
gameloop.networkSend(utils.unit("playerLeave")) levelloop.networkSend(utils.unit("playerLeave"))
end end
gameloop.world = world levelloop.world = world
end end

View File

@ -118,7 +118,7 @@ end
function layout.drawHash(container, x, y, simulate) function layout.drawHash(container, x, y, simulate)
local texture = gameloop.textures[container.hash] local texture = levelloop.textures[container.hash]
local scale = container.scale or 1 local scale = container.scale or 1
if not texture.image then if not texture.image then
texture.image = love.graphics.newImage(texture.data) texture.image = love.graphics.newImage(texture.data)
@ -153,7 +153,7 @@ function layout.bwColorPicker(container, x, y, simulate)
local iterationCount = (1.0 / granularity) local iterationCount = (1.0 / granularity)
maxx = x + pointSize * iterationCount maxx = x + pointSize * iterationCount
table.insert(uiState, { granularity = granularity, pointSize = pointSize, table.insert(layout.uiState, { granularity = granularity, pointSize = pointSize,
kind=container.kind, kind=container.kind,
x=x, x2=maxx, y=y, y2=y + pointSize }) x=x, x2=maxx, y=y, y2=y + pointSize })
else else
@ -196,7 +196,7 @@ function layout.colorPicker(container, x, y, simulate)
local iterationCount = (1.0 / granularity) + 1 local iterationCount = (1.0 / granularity) + 1
maxx = x + pointSize * iterationCount * iterationCount maxx = x + pointSize * iterationCount * iterationCount
table.insert(uiState, { granularity = granularity, pointSize = pointSize, table.insert(layout.uiState, { granularity = granularity, pointSize = pointSize,
kind=container.kind, kind=container.kind,
x=x, x2=maxx, y=y, y2=myy }) x=x, x2=maxx, y=y, y2=myy })
else else

View File

@ -80,7 +80,7 @@ function menu.mousepressed(mousex, mousey)
NETWORK_DEBUG = true NETWORK_DEBUG = true
firstclient = false firstclient = false
end end
local textures = gameloop.textures local textures = levelloop.textures
local names = { "Herbert", "Thorben", "Martin", "Heinrich", "Dietrich", "Markus", "Florian", "Helmut", "Willhelm", "Fritz", "Gustav", "Konrad", "Berta", "Charlotte", "Hildegard", "Lieselotte", "Gudrun", "Giesela", "Margarete", "Antonia", "Friederike", "Clotilde", "Marlies", "Hedwig", "Agathe" } local names = { "Herbert", "Thorben", "Martin", "Heinrich", "Dietrich", "Markus", "Florian", "Helmut", "Willhelm", "Fritz", "Gustav", "Konrad", "Berta", "Charlotte", "Hildegard", "Lieselotte", "Gudrun", "Giesela", "Margarete", "Antonia", "Friederike", "Clotilde", "Marlies", "Hedwig", "Agathe" }
local lastNames = { "Müller", "Schmidt", "Meier", "Bauer", "Werner", "Schumacher", "Bergmann", "Eisenhauer", "Heisenberg" } local lastNames = { "Müller", "Schmidt", "Meier", "Bauer", "Werner", "Schumacher", "Bergmann", "Eisenhauer", "Heisenberg" }
@ -89,7 +89,7 @@ function menu.mousepressed(mousex, mousey)
local serverEntry = menu.serverlist[serverID] local serverEntry = menu.serverlist[serverID]
local avatar = love.image.newImageData("textures/player/nephele/dog.png") local avatar = love.image.newImageData("textures/player/nephele/dog.png")
local avatarHash = love.data.hash("sha512", avatar:getString()) local avatarHash = love.data.hash("sha512", avatar:getString())
gameloop.init({ adress = serverEntry.host, port = serverEntry.port }, fullName, avatarHash) levelloop.init({ adress = serverEntry.host, port = serverEntry.port }, fullName, avatarHash)
layout.uiState = {} layout.uiState = {}
end end
end end

View File

@ -23,7 +23,7 @@ function physics.remove_solid(x, y, sizex, sizey)
asserts.number("physics.remove_solid", 4, x, y, sizex, sizey) asserts.number("physics.remove_solid", 4, x, y, sizex, sizey)
for coord_x=x, x + sizex-1 do for coord_x=x, x + sizex-1 do
for coord_y=y, y + sizey-1 do for coord_y=y, y + sizey-1 do
gameloop.Canvas.physics[coord_x*gameloop.world.x+coord_y] = nil levelloop.Canvas.physics[coord_x*levelloop.world.x+coord_y] = nil
end end
end end
end end
@ -33,7 +33,7 @@ function physics.draw_solid(x, y, sizex, sizey)
asserts.number("physics.draw_solid", 4, x, y, sizex, sizey) asserts.number("physics.draw_solid", 4, x, y, sizex, sizey)
for coord_x=x, x + sizex-1 do for coord_x=x, x + sizex-1 do
for coord_y=y, y + sizey-1 do for coord_y=y, y + sizey-1 do
gameloop.Canvas.physics[coord_x*gameloop.world.x+coord_y] = {0, 0, 0, true } levelloop.Canvas.physics[coord_x*levelloop.world.x+coord_y] = {0, 0, 0, true }
end end
end end
end end
@ -43,7 +43,7 @@ function draw_colision(x, y, x2, y2, pixelx, pixely)
utils.color_push() utils.color_push()
love.graphics.setLineWidth(1) love.graphics.setLineWidth(1)
love.graphics.setDefaultFilter("nearest", "nearest", 0) love.graphics.setDefaultFilter("nearest", "nearest", 0)
love.graphics.setCanvas(gameloop.Canvas.dbg2) love.graphics.setCanvas(levelloop.Canvas.dbg2)
if pixelx then if pixelx then
love.graphics.setColor(.6, 0, .6, 1) love.graphics.setColor(.6, 0, .6, 1)
love.graphics.rectangle("fill", x, y, x2, y2) love.graphics.rectangle("fill", x, y, x2, y2)
@ -62,7 +62,7 @@ function physics.is_blocked_x(x, y, sizex)
x, y = math.floor(x), math.floor(y) x, y = math.floor(x), math.floor(y)
asserts.number("physics.is_blocked_x", 3, x, y, sizex) asserts.number("physics.is_blocked_x", 3, x, y, sizex)
for coord_x=x ,x + sizex -1 do for coord_x=x ,x + sizex -1 do
if gameloop.Canvas.physics[coord_x * gameloop.world.x+y] and gameloop.Canvas.physics[coord_x*gameloop.world.x+y][4] then if levelloop.Canvas.physics[coord_x * levelloop.world.x+y] and levelloop.Canvas.physics[coord_x*levelloop.world.x+y][4] then
if PHYSICS_DEBUG then draw_colision(x, y, sizex, 1, coord_x, y) end if PHYSICS_DEBUG then draw_colision(x, y, sizex, 1, coord_x, y) end
return true return true
end end
@ -76,7 +76,7 @@ function physics.is_blocked_y(x, y, sizey)
x, y = math.floor(x), math.floor(y) x, y = math.floor(x), math.floor(y)
asserts.number("physics.is_blocked_y", 3, x, y, sizey) asserts.number("physics.is_blocked_y", 3, x, y, sizey)
for coord_y=y, y + sizey -1 do for coord_y=y, y + sizey -1 do
if gameloop.Canvas.physics[x*gameloop.world.x+coord_y] and gameloop.Canvas.physics[x*gameloop.world.x+coord_y][4] then if levelloop.Canvas.physics[x*levelloop.world.x+coord_y] and levelloop.Canvas.physics[x*levelloop.world.x+coord_y][4] then
if PHYSICS_DEBUG then draw_colision(x, y, 1, sizey, x, coord_y) end if PHYSICS_DEBUG then draw_colision(x, y, 1, sizey, x, coord_y) end
return true return true
end end
@ -90,14 +90,14 @@ function physics.keypressed( key, code, isrepeat)
if isrepeat then return end if isrepeat then return end
if camera.target == 0 then return end if camera.target == 0 then return end
player = players[camera.target] player = participants[camera.target]
if key == "p" then if key == "p" then
player.flying = not player.flying player.flying = not player.flying
if player.flying then if player.flying then
player.speed.y = 0 player.speed.y = 0
gameloop.networkSend(utils.unit("moveFlying", "true")) levelloop.networkSend(utils.unit("moveFlying", "true"))
else else
gameloop.networkSend(utils.unit("moveFlying", "false")) levelloop.networkSend(utils.unit("moveFlying", "false"))
end end
end end
end end
@ -105,7 +105,7 @@ end
function physics.input(dt) function physics.input(dt)
if camera.target == 0 then return end if camera.target == 0 then return end
player = players[camera.target] player = participants[camera.target]
local speedModified = dt * 20 local speedModified = dt * 20
if love.keyboard.isDown("rshift") or love.keyboard.isDown("lshift") if love.keyboard.isDown("rshift") or love.keyboard.isDown("lshift")
then then
@ -127,7 +127,7 @@ function physics.input(dt)
local posx = player.x + player.avatar:getWidth() local posx = player.x + player.avatar:getWidth()
local posy = player.y + player.avatar:getHeight() local posy = player.y + player.avatar:getHeight()
if physics.is_blocked_x(posx - player.avatar:getWidth(), posy, player.avatar:getWidth()) or if physics.is_blocked_x(posx - player.avatar:getWidth(), posy, player.avatar:getWidth()) or
player.y == gameloop.world.y - player.avatar:getHeight() then player.y == levelloop.world.y - player.avatar:getHeight() then
player.speed.y = -25 player.speed.y = -25
end end
end end
@ -135,16 +135,16 @@ end
function physics.cap_world(width, height, newx, newy, new_sx, new_sy) function physics.cap_world(width, height, newx, newy, new_sx, new_sy)
if newx > gameloop.world.x - width then if newx > levelloop.world.x - width then
newx = gameloop.world.x - width newx = levelloop.world.x - width
new_sx = 0 new_sx = 0
end end
if newx < 0 then if newx < 0 then
newx = 0 newx = 0
new_sx = 0 new_sx = 0
end end
if newy > gameloop.world.y - height then if newy > levelloop.world.y - height then
newy = gameloop.world.y - height newy = levelloop.world.y - height
new_sy = 0 new_sy = 0
end end
if newy < 0 then if newy < 0 then
@ -157,7 +157,7 @@ end
local SKIP = false local SKIP = false
function physics.update(dt) function physics.update(dt)
SKIP = false SKIP = false
for i, player in pairs(players) do for i, player in pairs(participants) do
assert(player.x and player.y and player.speed.y and player.speed.x, "Player " .. i .. " has an invalid position!") assert(player.x and player.y and player.speed.y and player.speed.x, "Player " .. i .. " has an invalid position!")
--friction --friction
@ -285,7 +285,7 @@ last.packet, last.x, last.y, last.speedx, last.speedy = 0, 0, 0, 0, 0
function physics.send_update(player, dt) function physics.send_update(player, dt)
if last.packet > 0.03 then if last.packet > 0.03 then
if last.x ~= player.x or last.y ~= player.y then if last.x ~= player.x or last.y ~= player.y then
gameloop.networkSend(utils.unit("moveUpdate", player.x, player.y, player.speed.x, player.speed.y)) levelloop.networkSend(utils.unit("moveUpdate", player.x, player.y, player.speed.x, player.speed.y))
last.packet = 0 last.packet = 0
last.x, last.y = player.x, player.y last.x, last.y = player.x, player.y
last.speedx, last.speedy = player.speedx, player.speedy last.speedx, last.speedy = player.speedx, player.speedy

View File

@ -37,14 +37,14 @@ function ui.keyreleased(key, _)
love.visible = function(visible) love.visible = function(visible)
if visible then if visible then
love.update = function(dt) love.update = function(dt)
gameloop.networkSync(dt) levelloop.networkSync(dt)
physics.update(dt) physics.update(dt)
camera.update(dt) camera.update(dt)
love.timer.sleep((1/60) -dt) love.timer.sleep((1/60) -dt)
end end
else else
love.update = function(dt) love.update = function(dt)
gameloop.networkSync(dt) levelloop.networkSync(dt)
physics.update(dt) physics.update(dt)
end end
end end
@ -53,9 +53,9 @@ function ui.keyreleased(key, _)
else else
love.visible = function(visible) love.visible = function(visible)
if visible then if visible then
love.update = gameloop.normalVisible love.update = levelloop.normalVisible
else else
love.update = gameloop.reducedVisible love.update = levelloop.reducedVisible
end end
end end
ui.draw(window.x, window.y) ui.draw(window.x, window.y)
@ -72,14 +72,14 @@ function ui.keyreleased(key, _)
love.visible = function(visible) love.visible = function(visible)
if visible then if visible then
love.update = function(dt) love.update = function(dt)
gameloop.networkSync(dt) levelloop.networkSync(dt)
drawing.input(dt) drawing.input(dt)
physics.update(dt) physics.update(dt)
camera.update(dt) camera.update(dt)
end end
else else
love.update = function(dt) love.update = function(dt)
gameloop.networkSync(dt) levelloop.networkSync(dt)
physics.update(dt) physics.update(dt)
end end
end end
@ -89,14 +89,14 @@ function ui.keyreleased(key, _)
if key == "return" and not love.keyboard.isDown("lalt") then if key == "return" and not love.keyboard.isDown("lalt") then
textEnabled = false textEnabled = false
if textEntry ~= "" then if textEntry ~= "" then
gameloop.networkSend(utils.unit("chatMessage", textEntry)) levelloop.networkSend(utils.unit("chatMessage", textEntry))
textEntry = "" textEntry = ""
end end
ui.draw(window.x, window.y) ui.draw(window.x, window.y)
love.keyboard.setTextInput(false) love.keyboard.setTextInput(false)
love.keyreleased = gameloop.keyreleased love.keyreleased = levelloop.keyreleased
love.keypressed = gameloop.keypressed love.keypressed = levelloop.keypressed
love.update = gameloop.normalVisible love.update = levelloop.normalVisible
elseif key == "backspace" then elseif key == "backspace" then
textEntry = string.sub(textEntry, 0, #textEntry -1) textEntry = string.sub(textEntry, 0, #textEntry -1)
ui.draw(window.x, window.y) ui.draw(window.x, window.y)
@ -104,8 +104,8 @@ function ui.keyreleased(key, _)
end end
love.keypressed = function(key, _) return end love.keypressed = function(key, _) return end
else else
love.keyreleased = gameloop.keyreleased love.keyreleased = levelloop.keyreleased
love.keypressed = gameloop.keypressed love.keypressed = levelloop.keypressed
end end
end end
@ -188,7 +188,7 @@ function ui.loadTextures(directory, container)
local status, imageData = pcall(love.image.newImageData, path); local status, imageData = pcall(love.image.newImageData, path);
if status then if status then
local hash = love.data.hash("sha512", imageData:getString()) local hash = love.data.hash("sha512", imageData:getString())
gameloop.textures[hash] = {data = imageData} levelloop.textures[hash] = {data = imageData}
container[file] = hash container[file] = hash
end end
end end
@ -198,7 +198,7 @@ end
function textureEntry(hash) function textureEntry(hash)
local texture = gameloop.textures[hash] local texture = levelloop.textures[hash]
assert(texture, "No texture found for textureentry?") assert(texture, "No texture found for textureentry?")
assert(texture.data, "No imagedata found for textureentry?") assert(texture.data, "No imagedata found for textureentry?")
if not texture.image then if not texture.image then
@ -228,7 +228,7 @@ end
function textureRun(entryTable, width) function textureRun(entryTable, width)
local textures = gameloop.textures local textures = levelloop.textures
local entries = {name = "naiveGrid", width = width - 20} local entries = {name = "naiveGrid", width = width - 20}
local entryTableSorted = {} local entryTableSorted = {}
@ -384,7 +384,7 @@ function ui.menuDrawer(w, h)
} }
end end
function ui.draw(w, h) function ui.draw(w, h)
window.x, window.y = w, h window.x, window.y = w, h
love.graphics.setCanvas(ui.buffer) love.graphics.setCanvas(ui.buffer)
@ -412,64 +412,65 @@ end
function ui.mousepressed(mousex, mousey) function ui.mousepressed(mousex, mousey)
local textures = gameloop.textures local textures = levelloop.textures
if menuVisible then if menuVisible then
for i, v in ipairs(layout.uiStateMenu) do for i, v in ipairs(layout.uiStateMenu) do
if mousex >= v.x and mousex <= v.x2 then if mousex >= v.x and mousex <= v.x2 and --hit testing
if mousey >= v.y and mousey <= v.y2 then mousey >= v.y and mousey <= v.y2 then
if v.kind == "button" then if v.kind == "button" then
if v.identifier == "save" then if v.identifier == "save" then
gameloop.networkSend("saveWorld") levelloop.networkSend("saveWorld")
ui.keyreleased("escape") ui.keyreleased("escape")
elseif v.identifier == "disconnect" then elseif v.identifier == "disconnect" then
gameloop.networkSend(utils.unit("playerLeave")) levelloop.networkSend(utils.unit("playerLeave"))
menu.init() menu.init()
elseif v.identifier == "sideBarScaleTwo" then elseif v.identifier == "sideBarScaleTwo" then
ui.sidebarScale = 2 ui.sidebarScale = 2
ui.draw(window.x, window.y) ui.draw(window.x, window.y)
ui.keyreleased("escape") ui.keyreleased("escape")
elseif v.identifier == "sideBarScaleOne" then elseif v.identifier == "sideBarScaleOne" then
ui.sidebarScale = 1 ui.sidebarScale = 1
ui.draw(window.x, window.y) ui.draw(window.x, window.y)
ui.keyreleased("escape") ui.keyreleased("escape")
end
end end
end end
return -- Return after the first hit...
end end
end end
else else
for i, v in ipairs(layout.uiState) do for i, v in ipairs(layout.uiState) do
if mousex >= v.x and mousex <= v.x2 then if mousex >= v.x and mousex <= v.x2 and
if mousey >= v.y and mousey <= v.y2 then mousey >= v.y and mousey <= v.y2 then
if v.kind == "picker" then if v.kind == "picker" then
assert(v.identifier, "No identifier in picker!") assert(v.identifier, "No identifier in picker!")
drawing.cursorHash = v.identifier drawing.cursorHash = v.identifier
drawing.cursor = textures[v.identifier] drawing.cursor = textures[v.identifier]
assert(drawing.cursor, "No cursor texture found!") assert(drawing.cursor, "No cursor texture found!")
ui.draw(window.x, window.y) ui.draw(window.x, window.y)
return return
elseif v.kind == "tab" then elseif v.kind == "tab" then
selectedTab = v.identifier selectedTab = v.identifier
ui.draw(window.x, window.y) ui.draw(window.x, window.y)
return return
elseif v.kind == "colorpicker" then elseif v.kind == "colorpicker" then
local scale = 1.0 / granularity print("Picker hit :D")
local red = math.floor((mousey - v.y) / v.pointSize) / scale local scale = 1.0 / granularity
local green = math.floor((mousex - v.x) / v.pointSize / (scale + 1)) / scale local red = math.floor((mousey - v.y) / v.pointSize) / scale
local blue = (math.floor((mousex - v.x) / v.pointSize) % (scale + 1)) / scale local green = math.floor((mousex - v.x) / v.pointSize / (scale + 1)) / scale
drawing.color = {red, green, blue, 1} local blue = (math.floor((mousex - v.x) / v.pointSize) % (scale + 1)) / scale
ui.draw(window.x, window.y) print("I think the color is " .. red .. ":" .. green .. ":" .. blue)
return drawing.color = {red, green, blue, 1}
elseif v.kind == "bwColorPicker" then ui.draw(window.x, window.y)
local scale = 1.0 / granularity return
local saturation = math.floor((mousex - v.x) / v.pointSize) / scale elseif v.kind == "bwColorPicker" then
drawing.color = {saturation, saturation, saturation, 1} local scale = 1.0 / granularity
ui.draw(window.x, window.y) local saturation = math.floor((mousex - v.x) / v.pointSize) / scale
return drawing.color = {saturation, saturation, saturation, 1}
end ui.draw(window.x, window.y)
return return
end end
return
end end
end end
end end

View File

@ -6,9 +6,56 @@ end
function love.load(args) function love.load(args)
if args[1] == "--server" then if args[1] == "--server" then
print("Starting server!") if not args[2]then
print("Missing server adress!")
love.event.quit()
return
end
local host = args[2]
local port = "11150"
if args[3] then port = args[3] end
local serverloop = require("server.main") local serverloop = require("server.main")
serverloop.init() print("Starting server! [" .. host .. "] <" .. port .. ">")
serverloop.init({host, port})
elseif args[1] == "--client" then
if not args[2]then
print("Missing server adress!")
love.event.quit()
return
end
dofile "lua/gameloop.lua"
dofile "lua/layout.lua"
dofile "lua/ui.lua"
dofile "lua/camera.lua"
dofile "lua/physics.lua"
dofile "lua/drawing.lua"
setmetatable(_G, {
__index = function(self, idx)
if rawget(self, idx) == nil then
error("attempted to read implicit global:" .. idx)
end
end
})
PHYSICS_DEBUG = false
NETWORK_DEBUG = true
local host = args[2]
local port = "11150"
if args[3] then port = args[3] end
local avatar = love.image.newImageData("textures/player/nephele/fallback.png")
local avatarHash = love.data.hash("sha512", avatar:getString())
levelloop.init({ adress = host, port = port }, "Fallback player", avatarHash)
elseif args[1] == "--help" then
print(" --server [host] <port>")
print(" Start a local server")
print("")
print(" --help")
print(" print this help")
return
else else
constants = require("server.constants") constants = require("server.constants")
local menu = require("lua.menuloop") local menu = require("lua.menuloop")

View File

@ -5,8 +5,8 @@ local rpc = require("server.rpc")
return function(commands) return function(commands)
function commands.chatMessage(clientID, args) function commands.chatMessage(clientID, args)
assert(clients[clientID]) assert(participants[clientID])
print("Chat " .. clients[clientID].name .. ": " .. args) print("Chat " .. participants[clientID].name .. ": " .. args)
broadcast(clientID, utils.unit("chatMessage", args)) broadcast(clientID, utils.unit("chatMessage", args))
end end
end end

View File

@ -5,30 +5,30 @@ require("server.compat")
return function(commands) return function(commands)
function commands.moveUpdate(clientID, args) function commands.moveUpdate(clientID, args)
if not clients[clientID] then rpc.print("moveUpdate: invalid clientid [" .. clientID .. "]") return end if not participants[clientID] then rpc.print("moveUpdate: invalid clientid [" .. clientID .. "]") return end
local x, y, speedx, speedy = table.unpack(util.resolve(args)) local x, y, speedx, speedy = table.unpack(util.resolve(args))
clients[clientID].x = x participants[clientID].x = x
clients[clientID].y = y participants[clientID].y = y
clients[clientID].speedx = speedx participants[clientID].speedx = speedx
clients[clientID].speedy = speedy participants[clientID].speedy = speedy
broadcast(clientID, util.unit("moveUpdate", x, y, speedx, speedy)) broadcast(clientID, util.unit("moveUpdate", x, y, speedx, speedy))
end end
function commands.moveFlying(clientID, args) function commands.moveFlying(clientID, args)
if not clients[clientID] then rpc.print("moveFlying: invalid clientid [" .. clientID .. "]") return end if not participants[clientID] then rpc.print("moveFlying: invalid clientid [" .. clientID .. "]") return end
broadcast(clientID, util.unit("moveFlying", args)) broadcast(clientID, util.unit("moveFlying", args))
end end
function commands.deletePhysics(clientID, args) function commands.deletePhysics(clientID, args)
if not clients[clientID] then rpc.print("deletePhysics: invalid clientid [" .. clientID .. "]") return end if not participants[clientID] then rpc.print("deletePhysics: invalid clientid [" .. clientID .. "]") return end
broadcast(clientID, util.unit("deletePhysics", args)) broadcast(clientID, util.unit("deletePhysics", args))
end end
function commands.drawPhysics(clientID, args) function commands.drawPhysics(clientID, args)
if not clients[clientID] then rpc.print("drawPhysics: invalid clientid [" .. clientID .. "]") return end if not participants[clientID] then rpc.print("drawPhysics: invalid clientid [" .. clientID .. "]") return end
broadcast(clientID, util.unit("drawPhysics", args)) broadcast(clientID, util.unit("drawPhysics", args))
end end
end end

View File

@ -3,7 +3,7 @@ local util = require("shared.utils")
return function(commands) return function(commands)
function commands.playerLeave(clientID) function commands.playerLeave(clientID)
print("Old client disconnected. id: [" .. clientID .. "]") print("Old client disconnected. id: [" .. clientID .. "]")
clients[clientID] = nil participants[clientID] = nil
broadcast(clientID, "playerLeave") broadcast(clientID, "playerLeave")
end end
end end

View File

@ -26,8 +26,8 @@ return function(commands)
local result = love.filesystem.createDirectory(directory) local result = love.filesystem.createDirectory(directory)
-- TODO check this result... -- TODO check this result...
if result then if result then
serverloop.Canvas.fg:newImageData():encode("png", directory .. "/fg.png") levelloop.Canvas.fg:newImageData():encode("png", directory .. "/fg.png")
serverloop.Canvas.bg:newImageData():encode("png", directory .. "/bg.png") levelloop.Canvas.bg:newImageData():encode("png", directory .. "/bg.png")
print("saved world. " .. savename) print("saved world. " .. savename)
broadcast("0", util.unit("saveWorld", "sucess", "" .. savename)) broadcast("0", util.unit("saveWorld", "sucess", "" .. savename))
return return

View File

@ -13,8 +13,7 @@ require("server.commands.physics")(commands)
require("server.commands.drawing")(commands) require("server.commands.drawing")(commands)
require("server.commands.chat")(commands) require("server.commands.chat")(commands)
require("server.commands.saving")(commands) require("server.commands.saving")(commands)
require("shared.commands")(commands)
sharedCommands = require("shared.commands")
local errorHandler = require("shared.error") local errorHandler = require("shared.error")
@ -24,17 +23,17 @@ require("server.unpriviliged_commands.init")(unpriviligedCommands)
server = assert(socket.udp()) server = assert(socket.udp())
local ip, port = nil, nil local ip, port = nil, nil
clients = {} participants = {}
serverloop = {} levelloop = {}
serverloop.textures = {} levelloop.textures = {}
server:settimeout(0) server:settimeout(0)
if not server or not socket then error("failed to listen on socket") end if not server or not socket then error("failed to listen on socket") end
function broadcast(clientID, message) function broadcast(clientID, message)
local payload = util.unit(protocolVersion, clientID, message) local payload = util.unit(protocolVersion, clientID, message)
for i, player in pairs(clients) do for i, player in pairs(participants) do
if i ~= clientID then if i ~= clientID then
server:sendto(payload, player.ip, player.port) server:sendto(payload, player.ip, player.port)
print("<= " .. payload) print("<= " .. payload)
@ -57,7 +56,7 @@ function loadTextures(directory, container)
local status, imageData = pcall(love.image.newImageData, path); local status, imageData = pcall(love.image.newImageData, path);
if status then if status then
local hash = love.data.hash("sha512", imageData:getString()) local hash = love.data.hash("sha512", imageData:getString())
serverloop.textures[hash] = {data = imageData} levelloop.textures[hash] = {data = imageData}
container[file] = hash container[file] = hash
end end
end end
@ -99,18 +98,18 @@ function mainloop(dt)
end end
function serverloop.init(host) function levelloop.init(host)
love.errorhandler = errorHandler.redscreen love.errorhandler = errorHandler.redscreen
status, value = server:setsockname(host[1], host[2]) status, value = server:setsockname(host[1], host[2])
if not status then if not status then
error("Server could not be started :( " .. value) error("Server could not be started :( " .. value)
end end
print("Server startup. listening on " .. server:getsockname()) print("Server startup. listening on " .. server:getsockname())
loadTextures("textures/blocks", serverloop.textures) loadTextures("textures/blocks", levelloop.textures)
serverloop.Canvas = {} levelloop.world = constants.world
serverloop.Canvas.fg = love.graphics.newCanvas(constants.world.x, constants.world.y) levelloop.Canvas = {}
serverloop.Canvas.bg = love.graphics.newCanvas(constants.world.x, constants.world.y) levelloop.Canvas.fg = love.graphics.newCanvas(levelloop.world.x, levelloop.world.y)
sharedCommands.commandsInit() levelloop.Canvas.bg = love.graphics.newCanvas(levelloop.world.x, levelloop.world.y)
print("Startup!") print("Startup!")
love.update = mainloop love.update = mainloop
love.draw = function() love.draw = function()
@ -123,4 +122,4 @@ function serverloop.init(host)
love.mousepressed = function() return end love.mousepressed = function() return end
end end
return serverloop return levelloop

View File

@ -1,49 +0,0 @@
print("Singleplayer Startup")
local constants = require("constants")
local rpc = require("rpc")
local socket = require("socket")
local v1_message = {}
require("physics")(v1_message)
require("world")(v1_message)
local server = assert(socket.udp())
local ip, port = nil, nil
local clientCount = 0
local clients = {}
client:settimeout(0)
local clientToServer = love.thread.getChannel ( "c2s" );
local serverToClient = love.thread.getChannel ( "s2c" );
assert(server:setsockname("*", 42069))
if not server or not socket then error("failed to listen on socket") end
while true do
::nw_next::
print("iteration start")
local data = clientToServer:demand()
print("received data from " .. ip)
for _, req in ipairs(rpc.parse_multiple(data)) do
if req.clientid == 0 then
count = count + 1
response = "rq" .. constants.US .. "cid" .. constants.US .. count
clients[count] = { ip = ip, port = port }
end
local response = rpc.eval(v1_message, req)
if response then
local payload = "poppyV001" .. constants.US .. "0" .. constants.US .. response
print("sending response " .. payload)
assert(serverToClient:send(payload))
else
print(req .. " had no return value!")
end
end
print("iteration over")
end
::nw_break::

View File

@ -10,10 +10,10 @@ return function(commands)
function commands.init(args, ip, port) function commands.init(args, ip, port)
clientCount = clientCount +1 clientCount = clientCount +1
local nickname, avatar = utils.nextStringRecord(args) local nickname, avatar = utils.nextStringRecord(args)
clients[clientCount] = { ip = ip, port = port, name = nickname, avatar = avatar } participants[clientCount] = { ip = ip, port = port, name = nickname, avatar = avatar }
print("New client connected. Granting id: [" .. clientCount .. "] IP: " .. ip .. " Port:" .. port) print("New client connected. Granting id: [" .. clientCount .. "] IP: " .. ip .. " Port:" .. port)
for i, client in pairs(clients) do for i, client in pairs(participants) do
if i ~= clientCount then if i ~= clientCount then
-- to Existing client -- to Existing client
local payload = utils.unit(protocolVersion, clientCount, "playerJoin", nickname, avatar) local payload = utils.unit(protocolVersion, clientCount, "playerJoin", nickname, avatar)

View File

@ -2,97 +2,96 @@ local player = require("lua.player")
local utils = require("shared.utils") local utils = require("shared.utils")
local commands = {} return function(commands)
local canvas = {} commands.moveUpdate = function(clientID, args)
local players if not participants[clientID] then return end
local textures local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local speedx, args = utils.nextIntRecord(args)
local speedy = utils.clean(args:gsub("^.-\31",""))
function commands.commandsInit() participants[clientID].x = x
if gameloop then -- client participants[clientID].y = y
CLIENT = true if not participants[clientID].speed then participants[clientID].speed = {} end
players = _G.players participants[clientID].speed.x = speedx
textures = gameloop.textures participants[clientID].speed.y = speedy
else
SERVER = true
players = _G.clients
textures = serverloop.textures
canvas.fg = serverloop.Canvas.fg
canvas.bg = serverloop.Canvas.bg
end end
end
function commands.commandsWorldInit() commands.moveFlying = function(clientID, args)
if CLIENT then if not participants[clientID] then return end
canvas.fg = gameloop.Canvas.fg participants[clientID].flying = (args == "true")
canvas.bg = gameloop.Canvas.bg
end end
end
commands.moveUpdate = function(clientID, args) commands.drawTexture = function(clientID, args)
if not players[clientID] then return end if _G.camera then
local x, args = utils.nextIntRecord(args) if clientID == camera.target then return end
local y, args = utils.nextIntRecord(args) end
local speedx, args = utils.nextIntRecord(args) local x, args = utils.nextIntRecord(args)
local speedy = utils.clean(args:gsub("^.-\31","")) local y, args = utils.nextIntRecord(args)
local layer, args = utils.nextStringRecord(args)
players[clientID].x = x local hashEncoded, args = utils.nextStringRecord(args)
players[clientID].y = y hash = love.data.decode("string", "base64", hashEncoded)
players[clientID].speed.x = speedx local r, args = utils.nextIntRecord(args)
players[clientID].speed.y = speedy local g, args = utils.nextIntRecord(args)
end local b, args = utils.nextIntRecord(args)
a = tonumber(args) or 1
if not textures[hash] then error("Failed to find hash!") return end
commands.moveFlying = function(clientID, args) if not textures[hash].image then
if not players[clientID] then return end textures[hash].image = love.graphics.newImage(textures[hash].data)
players[clientID].flying = (args == "true") end
end love.graphics.setCanvas(levelloop.Canvas[layer])
love.graphics.setBlendMode("alpha")
utils.color_push()
commands.drawTexture = function(clientID, args) love.graphics.setColor(r, g, b ,a )
if _G.camera then love.graphics.draw(textures[hash].image, x, y)
if clientID == camera.target then return end utils.color_pop()
love.graphics.setCanvas()
end end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local layer, args = utils.nextStringRecord(args) commands.deleteTexture = function(clientID, args)
local hashEncoded, args = utils.nextStringRecord(args) if _G.camera then
hash = love.data.decode("string", "base64", hashEncoded) if clientID == camera.target then return end
local r, args = utils.nextIntRecord(args) end
local g, args = utils.nextIntRecord(args) local x, args = utils.nextIntRecord(args)
local b, args = utils.nextIntRecord(args) local y, args = utils.nextIntRecord(args)
a = tonumber(args) or 1 local width, args = utils.nextIntRecord(args)
if not textures[hash] then error("Failed to find hash!") return end local height, layer = utils.nextIntRecord(args)
if not textures[hash].image then love.graphics.setCanvas(canvas[layer])
textures[hash].image = love.graphics.newImage(textures[hash].data) love.graphics.setBlendMode("replace")
end
love.graphics.setCanvas(canvas[layer])
love.graphics.setBlendMode("alpha")
utils.color_push() utils.color_push()
love.graphics.setColor(r, g, b ,a ) love.graphics.setColor(0,0,0,0)
love.graphics.draw(textures[hash].image, x, y) love.graphics.rectangle("fill", x, y, width, height)
utils.color_pop() utils.color_pop()
love.graphics.setCanvas() love.graphics.setBlendMode("alpha")
end love.graphics.setCanvas()
commands.deleteTexture = function(clientID, args)
if _G.camera then
if clientID == camera.target then return end
end end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local width, args = utils.nextIntRecord(args)
local height, layer = utils.nextIntRecord(args)
love.graphics.setCanvas(canvas[layer])
love.graphics.setBlendMode("replace")
utils.color_push()
love.graphics.setColor(0,0,0,0)
love.graphics.rectangle("fill", x, y, width, height)
utils.color_pop()
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas()
end
return commands commands.fillCanvas = function(clientID, args)
local layer, args = utils.nextStringRecord(args)
local hashEncoded, args = utils.nextStringRecord(args)
hash = love.data.decode("string", "base64", hashEncoded)
local r, args = utils.nextIntRecord(args)
local g, args = utils.nextIntRecord(args)
local b, args = utils.nextIntRecord(args)
a = tonumber(args)
love.graphics.setCanvas(levelloop.Canvas[layer])
love.graphics.clear()
utils.color_push()
love.graphics.setColor({r, g, b, a})
for x = 0, levelloop.world.x -levelloop.textures[hash].image:getPixelWidth(),
levelloop.textures[hash].image:getPixelWidth() do
for y = 0, levelloop.world.y -levelloop.textures[hash].image:getPixelHeight(),
levelloop.textures[hash].image:getPixelHeight() do
love.graphics.draw(levelloop.textures[hash].image, x, y)
end
end
utils.color_pop()
love.graphics.setCanvas()
end
end