Compare commits

...

4 Commits

Author SHA1 Message Date
Pascal Abresch 39bce76863 add server running info label 2022-08-04 21:40:20 +02:00
Pascal Abresch 540b25379f improve main menu, add nicer button 2022-08-04 21:40:08 +02:00
Pascal Abresch 4de4a5eb9f minor fix 2022-08-04 21:14:56 +02:00
Pascal Abresch 2f2a098ca6 Change some stuff 2022-08-04 21:06:21 +02:00
24 changed files with 555 additions and 517 deletions

View File

@ -1,7 +1,7 @@
love.conf = function(conf)
conf.window.height = 480
conf.window.height = 1000
conf.window.minheight = 480
conf.window.width = 640
conf.window.width = 1000
conf.window.minwidth = 640
conf.window.resizable = true
conf.window.vsync = -1

96
lua/commands.lua Normal file
View File

@ -0,0 +1,96 @@
local player = require("lua.player")
local utils = require("shared.utils")
local fonts = require("shared.fonts")
local commands = {}
local sharedCommands = require("lua.sharedCommands")
commands.commandsInit = sharedCommands.commandsInit
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.playerJoin = function(clientID, args)
local nickname, avatarEncoded = utils.nextStringRecord(args)
avatar = love.data.decode("string", "base64", avatarEncoded)
ui.addChatEntry("", nickname .. " Joined the game")
players[clientID] = player.newPlayer({name = nickname, avatar = gameloop.avatars[avatar].image})
players[clientID].label = love.graphics.newText(fonts.smallFont, nickname)
end
commands.playerLeave = function(clientID)
if players[clientID] then
local name = players[clientID].name
ui.addChatEntry("", name .. " Left the game")
players[clientID] = nil
end
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
name = players[clientID].name
end
ui.addChatEntry(players[clientID].name, args)
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

@ -3,16 +3,17 @@ function alignToGrid(num, thing)
return num - (num % thing)
end
local utils = require("shared.utils")
function drawing.clearAllCanvases()
love.graphics.setCanvas(gameloop.buffer.pixel.fg)
love.graphics.setCanvas(gameloop.Canvas.fg)
love.graphics.clear()
love.graphics.setCanvas(gameloop.buffer.pixel.bg)
love.graphics.setCanvas(gameloop.Canvas.bg)
love.graphics.clear()
love.graphics.setCanvas(gameloop.buffer.pixel.dbg)
love.graphics.setCanvas(gameloop.Canvas.dbg)
love.graphics.clear()
love.graphics.setCanvas()
gameloop.buffer.physics = {}
gameloop.Canvas.physics = {}
end
@ -23,7 +24,7 @@ end
function drawing.fillCanvas(layer, hash)
love.graphics.setCanvas(gameloop.buffer.pixel[layer])
love.graphics.setCanvas(gameloop.Canvas[layer])
love.graphics.clear()
for x = 0, gameloop.world.x -gameloop.textures[hash].image:getPixelWidth(),
gameloop.textures[hash].image:getPixelWidth() do
@ -37,7 +38,7 @@ end
function drawing.fillCanvasNetwork(layer, hash)
gameloop.networkSend(unit("fillCanvas", layer, love.data.encode("string", "base64", hash)))
gameloop.networkSend(utils.unit("fillCanvas", layer, love.data.encode("string", "base64", hash)))
drawing.fillCanvas(layer, hash)
end
@ -99,18 +100,17 @@ function drawing.input(dt)
if not (thisx == thisx) or not (thisy == thisy) then return end
local ctrlDown = love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl")
love.graphics.setBlendMode("replace")
if ctrlDown then
love.graphics.setCanvas(gameloop.buffer.pixel.bg)
love.graphics.setCanvas(gameloop.Canvas.bg)
else
love.graphics.setCanvas(gameloop.buffer.pixel.fg)
love.graphics.setCanvas(gameloop.Canvas.fg)
end
if love.mouse.isDown(1) then -- only delete
color_push()
utils.color_push()
love.graphics.setColor(drawing.color)
love.graphics.draw(cursor.image, thisx, thisy)
color_pop()
utils.color_pop()
if ctrlDown then
drawing.draw_texture(drawing.cursorHash, thisx, thisy, "bg", drawing.color)
else
@ -120,7 +120,8 @@ function drawing.input(dt)
cursor.image:getPixelHeight())
end
else
color_push()
love.graphics.setBlendMode("replace")
utils.color_push()
love.graphics.setColor(0,0,0,0)
love.graphics.rectangle("fill", thisx, thisy,
cursor.image:getPixelWidth(),
@ -137,9 +138,9 @@ function drawing.input(dt)
cursor.image:getPixelWidth(),
cursor.image:getPixelHeight())
end
color_pop()
utils.color_pop()
love.graphics.setBlendMode("alpha")
end
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas()
end
drawmouse.lastX = mousex
@ -155,7 +156,7 @@ function drawing.draw_texture(hash, x, y, layer, color)
if not color[4] then color[4] = 1 end
local last = drawing.lastTexture
if hash ~= last.hash or x ~= last.x or y ~= last.y or layer ~= last.layer then
gameloop.networkSend(unit("drawTexture", x, y,
gameloop.networkSend(utils.unit("drawTexture", x, y,
layer, love.data.encode("string", "base64", hash), color[1], color[2], color[3], color[4]))
end
last.hash, last.x, last.y, last.layer = hash, x, y, layer
@ -168,7 +169,7 @@ function drawing.del_texture(x, y, width, height, layer)
local last = drawing.lastTextureDel
if x ~= last.x or y ~= last.y or width ~= last.width
or height ~= last.height or layer ~= last.layer then
gameloop.networkSend(unit("deleteTexture", x, y, width, height, layer))
gameloop.networkSend(utils.unit("deleteTexture", x, y, width, height, layer))
last.x, last.y, last.width, last.height, last.layer = x, y, width, height, layer
end
end
@ -177,7 +178,7 @@ end
local lastDWP = { x = 0, y = 0, width = 0, height = 0}
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
gameloop.networkSend(unit("drawPhysics", x, y, width, height))
gameloop.networkSend(utils.unit("drawPhysics", x, y, width, height))
physics.draw_solid(x, y, width, height)
lastDWP.x, lastDWP.y, lastDWP.width, lastDWP.height = x, y, width, height
end
@ -187,12 +188,13 @@ end
local lastRMP = { x = 0, y = 0, width = 0, height = 0}
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
gameloop.networkSend(unit("deletePhysics", x, y, width, height))
gameloop.networkSend(utils.unit("deletePhysics", x, y, width, height))
physics.remove_solid(x, y, width, height)
lastRMP.x, lastRMP.y, lastRMP.width, lastRMP.height = x, y, width, height
end
end
function drawing.init()
local path = "textures/blocks/krock/Glass/03.png"
local texture = {data = love.image.newImageData(path),
@ -203,7 +205,6 @@ function drawing.init()
drawing.cursor = textures[drawing.cursorHash]
texture, path = nil, nil
local clientChannel = love.thread.getChannel ( "clientChannel" );
mouse.lastpos = {}
mouse.lastpos.x = 0

View File

@ -2,23 +2,30 @@ gameloop = {}
gameloop.world = nil
gameloop.textures = {}
gameloop.avatars = {}
local rpc = require("server.rpc")
local v2_message = require("lua.network")
commands = require("lua.commands")
local socket = require "socket"
local util = require("server.utils")
local utils = require("shared.utils")
local fonts = require("shared.fonts")
local rpc = require("server.rpc")
local constants = require("server.constants")
gameloop.nwChecklist = {}
gameloop.Canvas = {}
local count = 1
local function normalDraw()
if count == 1 then print("use canvas!") count = 2 end
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
-- Draw background
if drawBackground then
color_push()
utils.color_push()
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.setColor(1, 1, 1, 1)
love.graphics.draw(gameloop.buffer.pixel.bg, layerTransform)
color_pop()
love.graphics.draw(gameloop.Canvas.bg, layerTransform)
utils.color_pop()
end
-- draw player
@ -31,7 +38,7 @@ local function normalDraw()
love.graphics.draw(player.avatar, playerTransform)
if player.name then
if not player.label then
player.label = love.graphics.newText(ui.smallFont, player.name)
player.label = love.graphics.newText(fonts.smallFont, player.name)
end
local labelTransform = love.math.newTransform(
math.floor(player.x - (player.label:getWidth() / 2) +
@ -43,7 +50,7 @@ local function normalDraw()
end
-- Draw foreground
love.graphics.draw(gameloop.buffer.pixel.fg, layerTransform)
love.graphics.draw(gameloop.Canvas.fg, layerTransform)
-- Draw UI
love.graphics.draw(ui.buffer)
@ -54,10 +61,10 @@ local function debugDraw()
normalDraw()
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
love.graphics.draw(gameloop.buffer.pixel.dbg, layerTransform)
love.graphics.draw(gameloop.buffer.pixel.dbg2, layerTransform)
love.graphics.draw(gameloop.Canvas.dbg, layerTransform)
love.graphics.draw(gameloop.Canvas.dbg2, layerTransform)
love.graphics.setCanvas(gameloop.buffer.pixel.dbg2)
love.graphics.setCanvas(gameloop.Canvas.dbg2)
love.graphics.clear()
love.graphics.setCanvas()
end
@ -65,15 +72,15 @@ end
local function normalNetworkSend(args)
if clientID == "0" then print("Invalid clientID?") end
local request = "poppyV003" ..US.. clientID ..US.. args
local request = constants.protocolVersion ..US.. clientID ..US.. args
gameloop.client:send(request)
end
local function debugNetworkSend(args)
assert(clientID ~= 0)
local request = "poppyV003" ..US.. clientID ..US.. args
print("=> " .. util.pprint(request))
local request = constants.protocolVersion ..constants.US.. clientID ..constants.US.. args
print("=> " .. utils.pprint(request))
gameloop.client:send(request)
end
@ -89,7 +96,7 @@ function normalNetworkSync()
end
local response = rpc.validate(message)
if not response.errorMsg then
rpc.execute(v2_message, response.clientID, response.record)
rpc.execute(commands, response.clientID, response.record)
message = nil
else
error(errorMsg)
@ -102,7 +109,7 @@ function debugNetworkSync()
local message, errorString = nil, false
while not errorString do
local message, errorString = gameloop.client:receive()
if message then print("<= " .. util.pprint(message)) end
if message then print("<= " .. utils.pprint(message)) end
if not message then
if errorString == "timeout" then return else
menu.init()
@ -111,7 +118,7 @@ function debugNetworkSync()
end
local response = rpc.validate(message)
if not response.errorMsg then
rpc.execute(v2_message, response.clientID, response.record)
rpc.execute(commands, response.clientID, response.record)
message = nil
else
error(errorMsg)
@ -196,28 +203,29 @@ end
function gameloop.init(server, nickname, avatarHash)
love.errorhandler = errorhandler
local US = constants.US
--love.errorhandler = errorhandler
assert(server, "Gameloop called without server to connect to?")
assert(nickname, "Gameloop called without nickname?")
assert(avatarHash, "Gameloop called without avatar?")
gameloop.server = server
scale = 1
love.graphics.setDefaultFilter("nearest", "nearest", 0)
layer = true
grid = 16
color = {}
mouse = {}
window = {}
window.x, window.y = love.graphics.getDimensions()
players = {}
textures = {}
view = {}
view.x = 0
view.y = 0
@ -226,7 +234,8 @@ function gameloop.init(server, nickname, avatarHash)
-- Must be done now because it has to be ready before "init" returns from the server
-- which is /before/ the game world is loaded
gameloop.loadAvatars()
commands.commandsInit()
gameloop.client = socket.udp()
gameloop.client:setpeername(server.adress, server.port)
gameloop.client:settimeout(0)
@ -234,9 +243,9 @@ function gameloop.init(server, nickname, avatarHash)
print("Socketnname: " .. gameloop.client:getsockname())
print("Connecting to [" .. server.adress .."]:" .. server.port)
local request = "poppyV003" ..US.. "0" ..US.. 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)
if NETWORK_DEBUG then print("=> " .. util.pprint(request)) end
if NETWORK_DEBUG then print("=> " .. utils.pprint(request)) end
if not NETWORK_DEBUG then
gameloop.networkSend = normalNetworkSend
@ -250,9 +259,20 @@ function gameloop.init(server, nickname, avatarHash)
gameloop.networkSync(dt)
love.timer.sleep((1/60) -dt)
end
local infoFont
if love.filesystem.getInfo("fonts/font.ttf") then
infoFont = love.graphics.newFont("fonts/font.ttf", 45)
else
infoFont = love.graphics.newFont(45)
end
local message = love.graphics.newText(infoFont, "Connecting...")
love.graphics.draw(message, 40, 40, 0, 1, 1)
love.draw = function(dt)
love.graphics.present()
love.graphics.setColor(0.05, 0.05, 0.05)
love.graphics.rectangle("fill", 0, 0, window.x, window.y)
love.graphics.setColor(1, 1, 1)
love.graphics.draw(message, 40, 40, 0, 1, 1)
end
end
@ -293,17 +313,15 @@ end
function gameloop.loadworld(world)
-- Game connected!
love.errorhandler = errorhandlerNetwork
local buffer = {}
buffer.pixel = {}
buffer.pixel.fg = love.graphics.newCanvas(world.x, world.y)
buffer.pixel.bg = love.graphics.newCanvas(world.x, world.y)
--love.errorhandler = errorhandlerNetwork
print("make canvas!")
gameloop.Canvas.fg = love.graphics.newCanvas(world.x, world.y)
gameloop.Canvas.bg = love.graphics.newCanvas(world.x, world.y)
if PHYSICS_DEBUG then
buffer.pixel.dbg = love.graphics.newCanvas(world.x, world.y)
buffer.pixel.dbg2 = love.graphics.newCanvas(world.x, world.y)
gameloop.Canvas.dbg = love.graphics.newCanvas(world.x, world.y)
gameloop.Canvas.dbg2 = love.graphics.newCanvas(world.x, world.y)
end
buffer.physics = {}
gameloop.buffer = buffer
gameloop.Canvas.physics = {}
ui.init()
drawing.init()
@ -331,12 +349,13 @@ function gameloop.loadworld(world)
love.resize = function()
normalDraw()
ui.resize()
camera.resize()
end
love.quit = function()
gameloop.networkSend(unit("playerLeave"))
gameloop.networkSend(utils.unit("playerLeave"))
end
gameloop.world = world

View File

@ -1,18 +0,0 @@
setmetatable(_G, {
__index = function(self, idx)
if rawget(self, idx) == nil then
error("attempted to read implicit global:" .. idx)
end
end
})
PHYSICS_DEBUG = true
NETWORK_DEBUG = true
constants = require("server.constants")
US = string.char(31)
local menu = require("lua.menuloop")
function love.load()
menu.init()
end

View File

@ -1,25 +1,32 @@
layout = {}
uiState = {}
local layout = {}
layout.uiState = {}
local debugPrint = function(string)
local fonts = require("shared.fonts")
local utils = require("shared.utils")
local asserts = require("shared.asserts")
function layout.debugPrint(string)
--print(string)
end
function layout.canvasAndColor(container, x, y, simulate)
asserts.number("layout.canvasAndColor", 2, x, y)
if simulate then return layout.handle(container[1], x, y, simulate) end
color_push()
utils.color_push()
love.graphics.setCanvas(container.canvas)
x, y = layout.handle(container[1], x, y, simulate)
love.graphics.setCanvas()
color_pop()
utils.color_pop()
return x, y
end
function layout.rotate(container, x, y, simulate)
assert_num("layout.rotate", 2, x, y)
assert_num("layout.rotate (container)", container.rotation)
asserts.number("layout.rotate", 2, x, y)
asserts.number("layout.rotate (container)", container.rotation)
local transform = love.math.newTransform(0, 0, container.rotation)
local noTransform = love.math.newTransform(0, 0, 0)
love.graphics.replaceTransform(transform)
@ -30,7 +37,8 @@ end
function layout.frame(container, x, y, simulate)
assert_num("layout.frame", 2, x, y)
asserts.number("layout.frame", 2, x, y)
x2, y2 = layout.handle(container[1], x +1, y +1, simulate)
if not simulate then
love.graphics.rectangle("line", x, y, x2 -x, y2 -y)
@ -42,7 +50,7 @@ end
function layout.cursorSelect(container, x, y, simulate)
x2, y2 = layout.handle(container[1], x, y, simulate)
if not simulate then
table.insert(uiState, { identifier = container.identifier, kind=container.kind,
table.insert(layout.uiState, { identifier = container.identifier, kind=container.kind,
x=x, x2=x2, y=y, y2=y2 })
end
return x2, y2
@ -50,8 +58,10 @@ end
function layout.linewidth(container, x, y, simulate)
if simulate then return layout.handle(container[1], x, y, simulate) end
assert(container.width, "layout.linewidth (container) no container.width provided!")
if simulate then return layout.handle(container[1], x, y, simulate) end
local oldWidth = love.graphics.getLineWidth()
love.graphics.setLineWidth(container.width)
x, y = layout.handle(container[1], x, y, simulate)
@ -66,6 +76,7 @@ function layout.spacer(container, x, y, simulate)
"Argument container.width to layout.spacer must not be NaN!")
assert(container.height == container.height,
"Argument container.height to layout.spacer must not be NaN!")
local width = container.width or 0
local height = container.height or 0
if container[1] then
@ -100,7 +111,8 @@ end
function layout.bwColorPicker(container, x, y, simulate)
assert(x and y)
asserts.number("layout.bwColorPicker", 2, x, y)
local startx, starty = x, y
granularity = container.granularity or 0.04
local points = {}
@ -109,7 +121,7 @@ function layout.bwColorPicker(container, x, y, simulate)
local pointSize = container.pointSize or 8
if not simulate then
color_push()
utils.color_push()
love.graphics.setPointSize(pointSize)
for c=0, 1.0, granularity do
@ -117,7 +129,7 @@ function layout.bwColorPicker(container, x, y, simulate)
love.graphics.points(myx+(pointSize/2), y +(pointSize/2))
myx = myx + pointSize
end
color_pop()
utils.color_pop()
local iterationCount = (1.0 / granularity)
maxx = x + pointSize * iterationCount
@ -135,7 +147,8 @@ end
function layout.colorPicker(container, x, y, simulate)
assert(x and y)
asserts.number("layout.colorPicker", 2, x, y)
local startx, starty = x, y
granularity = container.granularity or 0.2
local points = {}
@ -144,7 +157,7 @@ function layout.colorPicker(container, x, y, simulate)
local pointSize = container.pointSize or 8
if not simulate then
color_push()
utils.color_push()
love.graphics.setPointSize(pointSize)
for r=0, 1.0, granularity do
@ -159,7 +172,7 @@ function layout.colorPicker(container, x, y, simulate)
if myx > endx then endx = myx end
myx = x
end
color_pop()
utils.color_pop()
local iterationCount = (1.0 / granularity) + 1
maxx = x + pointSize * iterationCount * iterationCount
@ -178,34 +191,39 @@ end
function layout.color(container, x, y, simulate)
if simulate then return layout.handle(container[1], x, y, simulate) end
assert(container.color, "layout.color Color!")
assert(#container.color == 3 or #container.color == 4)
color_push()
utils.color_push()
love.graphics.setColor(container.color)
x, y = layout.handle(container[1], x, y, simulate)
color_pop()
utils.color_pop()
return x, y
end
function layout.rect(container, x, y, simulate)
assert_num("layout.rect", 2, x, y)
assert_num("layout.rect (container)", 2, container.width, container.height)
if not simulate then
if container.color then
color_push()
love.graphics.setColor(container.color.r, container.color.g, container.color.b, container.color.a or 1)
asserts.number("layout.rect", 2, x, y)
asserts.number("layout.rect (container)", 2, container.width, container.height)
if simulate then return x + container.width, y + container.height end
if container.color then
utils.color_push()
love.graphics.setColor(container.color.r, container.color.g, container.color.b, container.color.a or 1)
love.graphics.rectangle(container.fill or "fill", x, y, container.width, container.height)
utils.color_pop()
else
love.graphics.rectangle(container.fill or "fill", x, y, container.width, container.height)
color_pop()
else
love.graphics.rectangle(container.fill or "fill", x, y, container.width, container.height)
end
end
return x + container.width, y + container.height
end
function layout.overlayRect(container, x, y, simulate)
assert_num("layout.overlayRect", 2, x, y)
asserts.number("layout.overlayRect", 2, x, y)
winx, winy = layout.handle(container[1], x, y, simulate)
width = winx -x
height = winy -y
@ -218,7 +236,7 @@ end
function layout.label(container, x, y, simulate)
if not container.font then container.font = ui.font end
if not container.font then container.font = fonts.normalFont end
local text = love.graphics.newText( container.font, container.text )
if not text then text = "Unset text!!" end
if not simulate then
@ -269,11 +287,11 @@ function layout.naiveGrid(container, startX, startY, simulate)
else
if not container[1] then return startX, startY end
end
for i, v in ipairs(container) do
retX, retY = layout.handle(v, workX, workY, simulate)
if retY > maxY then maxY = retY end
if retX > startX + width then
workY = maxY
workX = startX
@ -282,7 +300,7 @@ function layout.naiveGrid(container, startX, startY, simulate)
workX = retX
end
end
return maxX, maxY
end
@ -298,7 +316,7 @@ function layout.copySize(container, x, y, simulate)
return bigx, bigy
end
function layout.vertical(container, x, y, simulate)
local bigx = x
if not simulate then
@ -318,11 +336,14 @@ end
local depth = -1
function layout.handle(container, x, y, simulate)
assert_num("layout.handle", 2, x, y)
asserts.number("layout.handle", 2, x, y)
assert(container, "layout.handle called without container")
local name = container["name"]
assert(name, "layout.handle container without name")
assert(layout[name], "Unknown layout function " .. name .. " called")
depth = depth +1
local depthCursor = ""
for i=0, depth do
@ -330,22 +351,24 @@ function layout.handle(container, x, y, simulate)
end
if depth == 0 then
if simulate then
debugPrint("Starting simulation")
layout.debugPrint("Starting simulation")
else
debugPrint("Starting rendering")
layout.debugPrint("Starting rendering")
end
end
debugPrint(depthCursor.. ">" .. container.name)
layout.debugPrint(depthCursor.. ">" .. container.name)
x, y = layout[name](container, x, y, simulate)
assert_num("layout.handle" .. container.name .. " is not returning properly!", 2, x, y)
debugPrint(depthCursor.."<" .. container.name)
asserts.number("layout.handle" .. container.name .. " is not returning properly!", 2, x, y)
layout.debugPrint(depthCursor.."<" .. container.name)
depth = depth -1
if depth == -1 then
if simulate then
debugPrint("simulation ended\n")
layout.debugPrint("simulation ended\n")
else
debugPrint("rendering ended\n")
layout.debugPrint("rendering ended\n")
end
end
return x, y
end
return layout

View File

@ -4,6 +4,11 @@ menu.serverlist = {
{description = "A localhost server [ipv6]", host = "::1", port = "11150"}
}
local utils = require("shared.utils")
local fonts = require("shared.fonts")
local layout = require("lua.layout")
local altPressed, enterPressed = false, false
function menu.keyreleased(key, _)
if key == "lalt" then
@ -39,14 +44,45 @@ function menu.resize()
love.graphics.setCanvas()
end
local firstClient = true
function menu.mousepressed(mousex, mousey)
local textures = gameloop.textures
for i, v in ipairs(uiState) do
for i, v in ipairs(layout.uiState) do
if mousex >= v.x and mousex <= v.x2 then
if mousey >= v.y and mousey <= v.y2 then
if v.kind == "localServer" then
love.graphics.reset()
love.graphics.origin()
love.graphics.clear(.6, 0, .6)
love.graphics.setColor(1, 1, 1)
love.graphics.present()
print("Starting server!")
local serverloop = require("server.main")
serverloop.init()
end
if v.kind == "server" then
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" }
if firstClient then
print("Starting client!")
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
firstclient = false
end
local textures = gameloop.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 lastNames = { "Müller", "Schmidt", "Meier", "Bauer", "Werner", "Schumacher", "Bergmann", "Eisenhauer", "Heisenberg" }
local fullName = names[love.math.random(1, #names)] .. " " .. lastNames[love.math.random(1, #lastNames)]
local serverID = v.identifier
@ -54,7 +90,7 @@ function menu.mousepressed(mousex, mousey)
local avatar = love.image.newImageData("textures/player/nephele/dog.png")
local avatarHash = love.data.hash("sha512", avatar:getString())
gameloop.init({ adress = serverEntry.host, port = serverEntry.port }, fullName, avatarHash)
uiState = {}
layout.uiState = {}
end
end
end
@ -63,16 +99,19 @@ end
menu.serverentry = function(id, description, host, port)
return {name = "horizontal",
{name = "label", text = description },
{name = "spacer", width = 20 },
{name = "label", text = "[".. host .."]"},
{name = "label", text = ":".. port },
{name = "spacer", width = 25 },
{name = "cursorSelect", kind = "server", identifier = id,
{name = "drawTexture", texture = love.graphics.newImage("textures/menu/serverPlay.png")}}}
return {name = "cursorSelect", kind = "server", identifier = id,
{name = "horizontal",
{name = "drawTexture", texture = love.graphics.newImage("textures/menu/serverPlay.png")},
{name = "spacer", width = 10 },
{name = "label", text = description },
{name = "spacer", width = 20 },
{name = "label", text = "[".. host .."]", font = fonts.smallFont},
{name = "label", text = ":".. port, font = fonts.smallFont },
}
}
end
menu.layoutServerList = function()
local list = {name = "vertical"}
for i, v in ipairs(menu.serverlist) do
@ -87,28 +126,41 @@ menu.layout = {name ="vertical",
{name = "horizontal",
{name = "spacer", width = 20},
{name = "drawTexture", texture = love.graphics.newImage("ressources/Poppy.png")},
{name = "label", text = "Welcome to poppy!"},
{name = "label", font = fonts.bigFont, text = "Welcome to poppy!"},
},
{name = "horizontal",
{name = "spacer", width = 60},
{name = "vertical",
{name = "spacer", height = 60},
{name = "label", text = "Pick a server to join!"},
{name = "spacer", height = 20},
menu.layoutServerList()
{name = "cursorSelect", kind = "localServer", identifier = "::1",
{name = "horizontal",
{name = "drawTexture",
texture = love.graphics.newImage("textures/menu/serverPlay.png")
},
{name = "spacer", width = 10},
{name = "label", text = "Spin up a local server"},
}
},
{name = "spacer", width = 60},
{name = "vertical",
{name = "spacer", height = 60},
{name = "label", text = "Or pick a server to join!", font = fonts.headerFont},
{name = "spacer", height = 20},
menu.layoutServerList()
}
}
}
}
function drawMenu()
color_push()
utils.color_push()
love.graphics.setCanvas(menu.Canvas)
uiState = {}
love.graphics.clear( )
layout.handle(menu.layout, 0, 0)
love.graphics.setCanvas()
color_pop()
utils.color_pop()
end
@ -118,6 +170,7 @@ end
function menu.init()
print("init menu")
menu.width, menu.height = love.window.getMode()
menu.Canvas = love.graphics.newCanvas(menu.width, menu.height)
drawMenu()
@ -125,6 +178,7 @@ function menu.init()
love.keyreleased = menu.keyreleased
love.keypressed = menu.keypressed
love.mousepressed = menu.mousepressed
print("inited menu")
end
return menu

View File

@ -1,159 +0,0 @@
local player = require("lua.player")
local util = require("server.utils")
local v2_message = {}
v2_message.init = function(clientID, args)
local nickname, args = util.nextStringRecord(args)
local avatarEncoded, args = util.nextStringRecord(args)
local worldID, args = util.nextStringRecord(args)
local x, args = util.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
v2_message.ping = function(clientID)
gameloop.networkSend("pong")
end
v2_message.playerJoin = function(clientID, args)
local nickname, avatarEncoded = util.nextStringRecord(args)
avatar = love.data.decode("string", "base64", avatarEncoded)
ui.addChatEntry("", nickname .. " Joined the game")
players[clientID] = player.newPlayer({name = nickname, avatar = gameloop.avatars[avatar].image})
players[clientID].label = love.graphics.newText(ui.smallFont, nickname)
end
v2_message.playerLeave = function(clientID)
if players[clientID] then
local name = players[clientID].name
ui.addChatEntry("", name .. " Left the game")
players[clientID] = nil
end
end
v2_message.moveUpdate = function(clientID, args)
if not players[clientID] then return end
local x, args = util.nextIntRecord(args)
local y, args = util.nextIntRecord(args)
local speedx, args = util.nextIntRecord(args)
local speedy = util.clean(args:gsub("^.-\31",""))
players[clientID].x = x
players[clientID].y = y
players[clientID].speed.x = speedx
players[clientID].speed.y = speedy
end
v2_message.moveFlying = function(clientID, args)
if not players[clientID] then return end
players[clientID].flying = (args == "true")
end
v2_message.deletePhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.remove_solid(util.getIntRecords(4, args))
end
v2_message.drawPhysics = function(clientID, args)
if clientID == camera.target then return end
if not players[clientID] then return end
physics.draw_solid(util.getIntRecords(4, args))
end
v2_message.drawTexture = function(clientID, args)
if clientID == camera.target then return end
local x, args = util.nextIntRecord(args)
local y, args = util.nextIntRecord(args)
local layer, args = util.nextStringRecord(args)
local hash, args = util.nextStringRecord(args)
hash = love.data.decode("string", "base64", hash)
local r, args = util.nextIntRecord(args)
local g, args = util.nextIntRecord(args)
local b, a = util.nextIntRecord(args)
a = tonumber(a)
if not r or not g or not b then
r, g, b = 1, 1, 1
end
if not a then
a = 1
end
if not gameloop.textures[hash] then print("Failed to find hash!") return end
love.graphics.setBlendMode("replace")
if layer == "fg" then
love.graphics.setCanvas(gameloop.buffer.pixel.fg)
elseif layer == "bg" then
love.graphics.setCanvas(gameloop.buffer.pixel.bg)
end
if not gameloop.textures[hash].image then love.graphics.newImage(gameloop.textures[hash].data) end
color_push()
love.graphics.setColor(r, g, b ,a)
love.graphics.draw(gameloop.textures[hash].image, x, y)
color_pop()
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas()
end
v2_message.deleteTexture = function(clientID, args)
if clientID == camera.target then return end
local x, args = util.nextIntRecord(args)
local y, args = util.nextIntRecord(args)
local width, args = util.nextIntRecord(args)
local height, layer = util.nextIntRecord(args)
if layer == "fg" then
love.graphics.setCanvas(gameloop.buffer.pixel.fg)
elseif layer == "bg" then
love.graphics.setCanvas(gameloop.buffer.pixel.bg)
end
love.graphics.setBlendMode("replace")
color_push()
love.graphics.setColor(0,0,0,0)
love.graphics.rectangle("fill", x, y, width, height)
color_pop()
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas()
end
v2_message.chatMessage = function(clientID, args)
local name
if clientID == "0" then
name = ""
else
name = players[clientID].name
end
ui.addChatEntry(players[clientID].name, args)
end
v2_message.clearCanvas = function(clientID)
drawing.clearAllCanvases()
end
v2_message.fillCanvas = function(clientID, args)
local layer, hash = util.nextStringRecord(args)
hash = love.data.decode("string", "base64", hash)
drawing.fillCanvas(layer, hash)
end
return v2_message

View File

@ -1,5 +1,8 @@
physics = {}
local asserts = require("shared.asserts")
local utils = require("shared.utils")
function physics.keyreleased_debug(key, _)
if key == "kp4" then
player.x = player.x -1
@ -17,30 +20,30 @@ end
function physics.remove_solid(x, y, sizex, sizey)
assert_num("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_y=y, y + sizey-1 do
gameloop.buffer.physics[coord_x*gameloop.world.x+coord_y] = nil
gameloop.Canvas.physics[coord_x*gameloop.world.x+coord_y] = nil
end
end
end
function physics.draw_solid(x, y, sizex, sizey)
assert_num("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_y=y, y + sizey-1 do
gameloop.buffer.physics[coord_x*gameloop.world.x+coord_y] = {0, 0, 0, true }
gameloop.Canvas.physics[coord_x*gameloop.world.x+coord_y] = {0, 0, 0, true }
end
end
end
function draw_colision(x, y, x2, y2, pixelx, pixely)
color_push()
utils.color_push()
love.graphics.setLineWidth(1)
love.graphics.setDefaultFilter("nearest", "nearest", 0)
love.graphics.setCanvas(gameloop.buffer.pixel.dbg2)
love.graphics.setCanvas(gameloop.Canvas.dbg2)
if pixelx then
love.graphics.setColor(.6, 0, .6, 1)
love.graphics.rectangle("fill", x, y, x2, y2)
@ -51,15 +54,15 @@ function draw_colision(x, y, x2, y2, pixelx, pixely)
love.graphics.rectangle("fill", x, y, x2, y2)
end
love.graphics.setCanvas()
color_pop()
utils.color_pop()
end
function physics.is_blocked_x(x, y, sizex)
x, y = math.floor(x), math.floor(y)
assert_num("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
if gameloop.buffer.physics[coord_x * gameloop.world.x+y] and gameloop.buffer.physics[coord_x*gameloop.world.x+y][4] then
if gameloop.Canvas.physics[coord_x * gameloop.world.x+y] and gameloop.Canvas.physics[coord_x*gameloop.world.x+y][4] then
if PHYSICS_DEBUG then draw_colision(x, y, sizex, 1, coord_x, y) end
return true
end
@ -71,9 +74,9 @@ end
function physics.is_blocked_y(x, y, sizey)
x, y = math.floor(x), math.floor(y)
assert_num("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
if gameloop.buffer.physics[x*gameloop.world.x+coord_y] and gameloop.buffer.physics[x*gameloop.world.x+coord_y][4] then
if gameloop.Canvas.physics[x*gameloop.world.x+coord_y] and gameloop.Canvas.physics[x*gameloop.world.x+coord_y][4] then
if PHYSICS_DEBUG then draw_colision(x, y, 1, sizey, x, coord_y) end
return true
end
@ -85,16 +88,16 @@ end
function physics.keypressed( key, code, isrepeat)
if isrepeat then return end
if camera.target == 0 then return end
player = players[camera.target]
if key == "p" then
player.flying = not player.flying
if player.flying then
player.speed.y = 0
gameloop.networkSend(unit("moveFlying", "true"))
gameloop.networkSend(utils.unit("moveFlying", "true"))
else
gameloop.networkSend(unit("moveFlying", "false"))
gameloop.networkSend(utils.unit("moveFlying", "false"))
end
end
end
@ -282,7 +285,7 @@ last.packet, last.x, last.y, last.speedx, last.speedy = 0, 0, 0, 0, 0
function physics.send_update(player, dt)
if last.packet > 0.03 then
if last.x ~= player.x or last.y ~= player.y then
gameloop.networkSend(unit("moveUpdate", player.x, player.y, player.speed.x, player.speed.y))
gameloop.networkSend(utils.unit("moveUpdate", player.x, player.y, player.speed.x, player.speed.y))
last.packet = 0
last.x, last.y = player.x, player.y
last.speedx, last.speedy = player.speedx, player.speedy

86
lua/sharedCommands.lua Normal file
View File

@ -0,0 +1,86 @@
local player = require("lua.player")
local utils = require("shared.utils")
local commands = {}
local canvas = {}
local players
local textures
function commands.commandsInit()
if gameloop then -- client
canvas.fg = gameloop.Canvas.fg
canvas.bg = gameloop.Canvas.bg
players = _G.players
textures = gameloop.textures
else
canvas.fg = serverloop.Canvas.fg
canvas.bg = serverloop.Canvas.bg
players = _G.clients
textures = serverloop.textures
end
end
commands.moveUpdate = function(clientID, args)
if not players[clientID] then return end
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",""))
players[clientID].x = x
players[clientID].y = y
players[clientID].speed.x = speedx
players[clientID].speed.y = speedy
end
commands.moveFlying = function(clientID, args)
if not players[clientID] then return end
players[clientID].flying = (args == "true")
end
commands.drawTexture = function(clientID, args)
if clientID == camera.target then return end
local x, args = utils.nextIntRecord(args)
local y, args = utils.nextIntRecord(args)
local layer, args = utils.nextStringRecord(args)
local hash, args = utils.nextStringRecord(args)
hash = love.data.decode("string", "base64", hash)
local r, args = utils.nextIntRecord(args)
local g, args = utils.nextIntRecord(args)
local b, a = utils.nextIntRecord(args)
a = tonumber(a)
if not gameloop.textures[hash] then print("Failed to find hash!") return end
love.graphics.setBlendMode("replace")
love.graphics.setCanvas(canvas[layer])
love.graphics.setCanvas(canvas.bg)
if not textures[hash].image then love.graphics.newImage(textures[hash].data) end
utils.color_push()
love.graphics.setColor(r, g, b ,a)
love.graphics.draw(textures[hash].image, x, y)
utils.color_pop()
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas()
end
commands.deleteTexture = function(clientID, args)
if clientID == camera.target then return 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

View File

@ -1,14 +1,9 @@
ui = {}
ui.textureTree = nil
if love.filesystem.getInfo("fonts/font.ttf") then
ui.smallFont = love.graphics.newFont("fonts/font.ttf", 14)
ui.font = love.graphics.newFont("fonts/font.ttf", 20)
ui.bigFont = love.graphics.newFont("fonts/font.ttf", 45)
else
ui.smallFont = love.graphics.newFont(14)
ui.font = love.graphics.newFont(20)
ui.bigFont = love.graphics.newFont(45)
end
local layout = require("lua.layout")
local utils = require("shared.utils")
ui.sidebarScale = 1
ui.sidebarWidth = 13 * 16
@ -62,7 +57,7 @@ function ui.keyreleased(key, _)
if key == "return" and not love.keyboard.isDown("lalt") then
textEnabled = false
if textEntry ~= "" then
gameloop.networkSend(unit("chatMessage", textEntry))
gameloop.networkSend(utils.unit("chatMessage", textEntry))
textEntry = ""
end
ui.draw(window.x, window.y)
@ -98,11 +93,11 @@ function ui.chatEntry()
fill = "fill",
color = { r = .1, g = .1, b = .1, .7 }
},
{name = "frame",
{name = "label",
text = passedEntry
{name = "frame",
{name = "label",
text = passedEntry
}
}
}
}
return chatEntry
end
@ -126,22 +121,22 @@ function ui.addChatEntry(user, message)
end
local entry = {name = "rotate",
rotation = 0, -- OKAY DIEGO >:(
{name = "copySize",
{name = "rect",
fill = "fill",
color = { r = .1, g = .1, b = .1, a = .6 }
{name = "copySize",
{name = "rect",
fill = "fill",
color = { r = .1, g = .1, b = .1, a = .6 }
},
{name = "vertical",
{name = "label",
text = chatText,
font = ui.smallFont
},
{name = "vertical",
{name = "label",
text = chatText,
font = ui.smallFont
},
{name = "spacer",
height = 2
}
{name = "spacer",
height = 2
}
}
}
}
table.insert(chatentries, entry)
ui.draw(window.x, window.y)
end
@ -180,7 +175,7 @@ function textureEntry(hash)
local width = texture.image:getWidth()
local height = texture.image:getHeight()
if drawing and drawing.cursorHash and hash == drawing.cursorHash then
return{name = "overlayRect",
return {name = "overlayRect",
fill = "line",
{name = "drawHash",
hash = hash,
@ -188,7 +183,7 @@ function textureEntry(hash)
}
}
else
return{name = "cursorSelect",
return {name = "cursorSelect",
identifier = hash,
kind = "picker",
{name = "drawHash",
@ -204,7 +199,7 @@ function textureRun(entryTable, width)
local textures = gameloop.textures
local entries = {name = "naiveGrid", width = width - 20}
local entryTableSorted = {}
-- Sort the entries alphapetically (or well, probably more... "byte compared") :)
-- This implies that in <author>/<packname>/<fileName> the fileName controls where
-- the texture lands in the block drawer, smaller lands further left.
@ -212,7 +207,7 @@ function textureRun(entryTable, width)
table.insert(entryTableSorted, {name = iter, entry = entry})
end
table.sort(entryTableSorted, function(k1, k2) return k1.name < k2.name end)
for iter, entry in pairs(entryTableSorted) do
if not textures[entry.entry].image then
textures[entry.entry].image = love.graphics.newImage(textures[entry.entry].data)
@ -245,7 +240,10 @@ function ui.blockDrawer(textureTree, w, h, container)
table.insert(container, {name = "label", text = pack})
table.insert(container,
{name = "color",
color = drawing.color,
color = drawing.color or {1, 1, 1},
--[[ HACK! remove the 1, 1, 1.
drawing.color should be set!
]]--
textureRun(subTree, w)
})
end
@ -267,7 +265,7 @@ function ui.testDrawer(w, h)
end
local selectedTab = "help"
local selectedTab = "blocks"
function ui.tabDrawer(textureTree, w, h)
local labels
local helpTab = {name = "label",
@ -296,7 +294,7 @@ function ui.tabDrawer(textureTree, w, h)
},
{name = "spacer",
width = 5
},
},
{name = "cursorSelect",
identifier = "disconnect",
kind = "button",
@ -361,7 +359,7 @@ end
function ui.draw(w, h)
window.x, window.y = w, h
color_push()
utils.color_push()
love.graphics.setCanvas(ui.buffer)
uiState = {}
love.graphics.clear( )
@ -374,14 +372,14 @@ function ui.draw(w, h)
layout.handle(chatLayout, 0, window.y - sizey)
end
layout.handle(ui.chatlog(), 25, 90)
color_pop()
utils.color_pop()
love.graphics.setCanvas()
end
function ui.mousepressed(mousex, mousey)
local textures = gameloop.textures
for i, v in ipairs(uiState) do
for i, v in ipairs(layout.uiState) do
if mousex >= v.x and mousex <= v.x2 then
if mousey >= v.y and mousey <= v.y2 then
if v.kind == "picker" then
@ -411,7 +409,7 @@ function ui.mousepressed(mousex, mousey)
return
elseif v.kind == "button" then
if v.identifier == "disconnect" then
gameloop.networkSend(unit("playerLeave"))
gameloop.networkSend(utils.unit("playerLeave"))
menu.init()
return
elseif v.identifier == "increaseUISize" then

View File

@ -1,60 +0,0 @@
local colorstack = {}
function color_push()
local depth = #colorstack +1
colorstack[depth] = {}
colorstack[depth].r, colorstack[depth].g, colorstack[depth].b,
colorstack[depth].a = love.graphics.getColor()
end
function color_pop()
love.graphics.setColor(colorstack[#colorstack].r, colorstack[#colorstack].g,
colorstack[#colorstack].b, colorstack[#colorstack].a)
table.remove(colorstack, #colorstack)
end
function assert_num(name, count, ...)
local args = { ... }
for i = 1, count do
assert(args[i] ~= nil, "Argument " .. i .. " to " .. name .. " may not be nil and must be an int!")
assert(type(args[i]) == "number", "Argument " .. i .. " to " .. name .. " must be an int!")
assert(args[i] == args[i], "Argument " .. i .. " to " .. name .. " must not be NaN!")
end
end
function assert_num_or_nil(name, count, ...)
local args = { ... }
for i = 1, count do
if (args[i] ~= nil) then
assert(type(args[i]) == "number", "Argument " .. i .. " to " .. name .. " can only be of type int!")
assert(args[i] == args[i], "Argument " .. i .. " to " .. name .. " may not be NaN!")
end
end
end
local recordSeperator = string.char(30)
local unitSeperator = string.char(31)
function unit(...)
local args = { ... }
local string = args[1]
for i=2, #args do
string = string .. unitSeperator .. args[i]
end
return string
end
function record(...)
local args = { ... }
local string = args[1]
for i=2, #args do
string = string .. recordSeperator .. args[i]
end
return string
end

View File

@ -2,11 +2,16 @@ function dofile(fileString)
local chunk = love.filesystem.load(fileString)
chunk()
end
dofile "lua/gameloop.lua"
dofile "lua/utils.lua"
dofile "lua/layout.lua"
dofile "lua/init.lua"
dofile "lua/ui.lua"
dofile "lua/camera.lua"
dofile "lua/physics.lua"
dofile "lua/drawing.lua"
function love.load(args)
if args[1] == "--server" then
print("Starting server!")
local serverloop = require("server.main")
serverloop.init()
else
constants = require("server.constants")
local menu = require("lua.menuloop")
menu.init()
end
end

BIN
ressources/Icons/PlayButton Normal file

Binary file not shown.

View File

@ -1,11 +1,12 @@
local constants = require("constants")
local util = require("utils")
local rpc = require("rpc")
local utils = require("shared.utils")
local constants = require("server.constants")
local rpc = require("server.rpc")
return function(commands)
function commands.chatMessage(clientID, args)
assert(clients[clientID])
print("Chat " .. clients[clientID].name .. ": " .. args)
broadcast(clientID, util.unit("chatMessage", args))
broadcast(clientID, utils.unit("chatMessage", args))
end
end

View File

@ -1,6 +1,7 @@
local constants = require("constants")
local util = require("utils")
local rpc = require("rpc")
local util = require("shared.utils")
local constants = require("server.constants")
local rpc = require("server.rpc")
return function(commands)
function commands.drawTexture(clientID, args)

View File

@ -1,7 +1,7 @@
local constants = require("constants")
local util = require("utils")
local rpc = require("rpc")
require("compat")
local constants = require("server.constants")
local util = require("shared.utils")
local rpc = require("server.rpc")
require("server.compat")
return function(commands)
function commands.moveUpdate(clientID, args)

View File

@ -1,4 +1,4 @@
local util = require("utils")
local util = require("shared.utils")
return function(commands)
function commands.playerLeave(clientID)

View File

@ -3,4 +3,9 @@ return {
US = string.char(31),
protocolVersion = "poppyV003",
world = {
x = 3000,
y = 3000,
id = "NYAAA"
}
}

View File

@ -1,30 +1,36 @@
print("Startup!")
local constants = require("constants")
protocolVersion = constants.protocolVersion
local rpc = require("rpc")
local socket = require("socket")
local util = require("utils")
local fonts = require("shared.fonts")
local constants = require("server.constants")
local rpc = require("server.rpc")
local util = require("shared.utils")
protocolVersion = constants.protocolVersion
local commands = {}
require("commands/players")(commands)
require("commands/physics")(commands)
require("commands/drawing")(commands)
require("commands/chat")(commands)
require("server.commands.players")(commands)
require("server.commands.physics")(commands)
require("server.commands.drawing")(commands)
require("server.commands.chat")(commands)
local unpriviligedCommands = {}
require("unpriviliged_commands/init")(unpriviligedCommands)
require("server.unpriviliged_commands.init")(unpriviligedCommands)
server = assert(socket.udp())
local ip, port = nil, nil
clients = {}
serverloop = {}
serverloop.textures = {}
server:settimeout(0)
assert(server:setsockname("*", 11150))
print(server:getsockname())
local socketString = server:getsockname()
print(socketString)
if not server or not socket then error("failed to listen on socket") end
print("Server startup.")
function broadcast(clientID, message)
local payload = util.unit(protocolVersion, clientID, message)
@ -37,7 +43,30 @@ function broadcast(clientID, message)
end
function love.update(dt)
function loadTextures(directory, container)
if not container then container = {} end
local entries = love.filesystem.getDirectoryItems(directory)
if #entries == 0 then return container end
for i, file in pairs(entries) do
local path = directory .."/".. file
local entry = love.filesystem.getInfo(path)
if entry.type == "directory" and file ~= ".git" then
container[file] = {}
container[file] = loadTextures(path, container[file])
elseif entry.type == "file" or entry.type == "symlink" then
local status, imageData = pcall(love.image.newImageData, path);
if status then
local hash = love.data.hash("sha512", imageData:getString())
serverloop.textures[hash] = {data = imageData}
container[file] = hash
end
end
end
return container
end
function mainloop(dt)
local data, ip, port
data, ip, port = server:receivefrom()
if not data then
@ -68,3 +97,23 @@ function love.update(dt)
end
end
end
function serverloop.init()
loadTextures("textures/blocks", serverloop.textures)
serverloop.Canvas = {}
serverloop.Canvas.fg = love.graphics.newCanvas(constants.world.x, constants.world.y)
serverloop.Canvas.bg = love.graphics.newCanvas(constants.world.x, constants.world.y)
print("Startup!")
love.update = mainloop
love.draw = function()
love.graphics.clear(.2, 0, .2)
love.graphics.print("Poppy server is running.", fonts.normalFont, 20, 20)
love.graphics.print("listening on " .. socketString, fonts.normalFont, 20, 50)
return end
love.keyreleased = function() return end
love.keypressed = function() return end
love.mousepressed = function() return end
end
return serverloop

View File

@ -1,38 +1,31 @@
local constants = require("constants")
local util = require("utils")
local rpc = require("rpc")
local utils = require("shared.utils")
local constants = require("server.constants")
local rpc = require("server.rpc")
local clientCount = 0
local world = {
x = 3000,
y = 3000,
id = "NYAAA"
}
return function(commands)
function commands.init(args, ip, port)
clientCount = clientCount +1
local nickname, avatar = util.nextStringRecord(args)
local nickname, avatar = utils.nextStringRecord(args)
clients[clientCount] = { ip = ip, port = port, name = nickname, avatar = avatar }
print("New client connected. Granting id: [" .. clientCount .. "] IP: " .. ip .. " Port:" .. port)
for i, client in pairs(clients) do
if i ~= clientCount then
print("Introducing client[" .. i .. "] and client[" .. clientCount .. "]")
-- to Existing client
local payload = util.unit(protocolVersion, clientCount, "playerJoin", nickname, avatar)
print("<= " .. util.pprint(payload))
local payload = utils.unit(protocolVersion, clientCount, "playerJoin", nickname, avatar)
server:sendto(payload, client.ip, client.port)
-- to New client
local payload = util.unit(protocolVersion, i, "playerJoin", client.name, client.avatar)
print("<= " .. util.pprint(payload))
local payload = utils.unit(protocolVersion, i, "playerJoin", client.name, client.avatar)
server:sendto(payload, ip, port)
end
end
-- Client response
local response = util.unit(protocolVersion, clientCount, "init", nickname, avatar, world.id, world.x, world.y)
local response = utils.unit(protocolVersion, clientCount, "init", nickname, avatar, constants.world.id, constants.world.x, constants.world.y)
server:sendto(response, ip, port)
end
end

View File

@ -1,59 +0,0 @@
local tempTable = {}
function tempTable.unit(...)
local args = { ... }
local string = args[1]
assert(string, "No args to unit!")
for i=2, #args do
--print(type(string) .. "with" .. type(args[i]))
string = string .. string.char(31) .. args[i]
end
return string
end
function tempTable.resolve(record)
local tTable = {}
for entry in record:gmatch("[^\31]+") do
table.insert(tTable, entry)
end
return tTable
end
function tempTable.clean(record)
assert(type(record) == "string")
return record:gsub("\31", "")
end
function tempTable.pprint(record)
local cleaned, _ = record:gsub("\31","|")
return cleaned
end
function tempTable.nextIntRecord(record)
local nextR = tempTable.clean(record:match("^.-\31"))
record = record:gsub("^.-\31","")
return tonumber(nextR), record
end
function tempTable.nextStringRecord(record)
local nextR = tempTable.clean(record:match("^.-\31"))
record = record:gsub("^.-\31","")
return nextR, record
end
function tempTable.getIntRecords(number, record)
local tTable = {}
local nextR
for i = 1, number -1 do
nextR, record = tempTable.nextIntRecord(record)
table.insert(tTable, nextR)
end
local last = tempTable.clean(record:gsub("^.-\31",""))
table.insert(tTable, tonumber(last))
return unpack(tTable)
end
return tempTable

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB