128 lines
3.7 KiB
Lua
128 lines
3.7 KiB
Lua
local socket = require("socket")
|
|
|
|
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("server.commands.players")(commands)
|
|
require("server.commands.physics")(commands)
|
|
require("server.commands.chat")(commands)
|
|
require("server.commands.saving")(commands)
|
|
require("shared.commands")(commands)
|
|
|
|
local format = require("shared.networkFormat")
|
|
|
|
local errorHandler = require("shared.error")
|
|
|
|
local unpriviligedCommands = {}
|
|
require("server.unpriviliged_commands.init")(unpriviligedCommands)
|
|
|
|
server = assert(socket.udp())
|
|
local ip, port = nil, nil
|
|
|
|
participants = {}
|
|
|
|
levelloop = {}
|
|
levelloop.textures = {}
|
|
|
|
server:settimeout(0)
|
|
if not server or not socket then error("failed to listen on socket") end
|
|
|
|
local function remoteCallTarget(target, clientID, name, ...)
|
|
local request = "PPY\x03" .. format.encodeFunction(name, clientID, ...)
|
|
server:sendto(request, target.ip, target.port)
|
|
end
|
|
|
|
|
|
function broadcast(clientID, name, ...)
|
|
for i, player in pairs(participants) do
|
|
if i ~= clientID then
|
|
remoteCallTarget(player, clientID, name, ...)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
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())
|
|
levelloop.textures[hash] = {data = imageData}
|
|
container[file] = hash
|
|
end
|
|
end
|
|
end
|
|
return container
|
|
end
|
|
|
|
love.window.minimize( )
|
|
love.window.setTitle( "Poppy server" )
|
|
function mainloop(dt)
|
|
|
|
local data, ip, port
|
|
data, ip, port = server:receivefrom()
|
|
if not data then
|
|
if ip == "timeout" then return else
|
|
print(ip)
|
|
end
|
|
end
|
|
local protocolVersion, index = string.unpack("<c4", data, index)
|
|
if protocolVersion ~= "PPY\x03" then
|
|
print("Dropping packet with invalid protocol " .. protocolVersion)
|
|
else
|
|
local DecoderType, index = string.unpack("<I1", data, index)
|
|
if (DecoderType == 0x81) then
|
|
name, clientID, args = format.decodeFunction(data, index)
|
|
if clientID == 0 then
|
|
unpriviligedCommands[name](ip, port, table.unpack(args))
|
|
else
|
|
commands[name](clientID, table.unpack(args))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function levelloop.init(host)
|
|
love.errorhandler = errorHandler.redscreen
|
|
status, value = server:setsockname(host[1], host[2])
|
|
if not status then
|
|
error("Server could not be started :( " .. value)
|
|
end
|
|
local ip, port =server:getsockname()
|
|
print("Server startup. listening on " .. ip .. " [".. port .."]")
|
|
loadTextures("textures/blocks", levelloop.textures)
|
|
levelloop.world = constants.world
|
|
levelloop.Canvas = {}
|
|
levelloop.Canvas.fg = love.graphics.newCanvas(levelloop.world.x, levelloop.world.y)
|
|
levelloop.Canvas.bg = love.graphics.newCanvas(levelloop.world.x, levelloop.world.y)
|
|
print("Startup!")
|
|
SERVER = true
|
|
CLIENT = false
|
|
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 " .. ip .. " [".. port .."]" , fonts.normalFont, 20, 50)
|
|
return end
|
|
love.keyreleased = function() return end
|
|
love.keypressed = function() return end
|
|
love.mousepressed = function() return end
|
|
end
|
|
|
|
return levelloop
|