Git Product home page Git Product logo

alloplace's Introduction

Alloverse Placeserv

Server component of Alloverse. Basically a multiplayer game server, but for window manager-y things.

Setup

  • git submodule update --init --recursive
  • cd marketplace && ./bootstrap.sh

then...

macOS

  • brew install asdf version manager for a bunch or languages. See https://asdf-vm.com/#/core-manage-asdf for more setup instructions
  • asdf plugin add erlang && asdf plugin add elixir
  • asdf install erlang 22.3 && asdf install elixir 1.9
  • export CPATH=~/.asdf/installs/erlang/22.3//usr/include for erlang headers
  • mix deps.get

Ubuntu (including Ubuntu-on-Windows)

  • wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
  • sudo dpkg -i erlang-solutions_1.0_all.deb; rm erlang-solutions_1.0_all.deb
  • sudo apt-get update
  • sudo apt-get install esl-erlang
  • sudo apt-get install elixir cmake clang openssl
  • mix deps.get

Run

  • mix run --no-halt

Docker

  • docker build -t alloplace .
  • ALLOPLACE_NAME="lol" docker run -p 21337:21337/udp -it alloplace

Adding a bundled app

  1. Add submodule: git submodule add <repo url> alloapp/<name>
  2. Add to whitelist in placeentity.ex:206 - or appname = "<name>"
  3. Add assist fetch to Dockerfile: RUN cd alloapps/<name>; ./allo/assist fetch

alloplace's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

alloplace's Issues

Improve error handling and supervisor structure

Right now, if any client sends illegal data, the mm and the server and all their children die and are restarted. the mm and AllonetPort are restarted badly, so that the old udp port is kept busy. Basically, the server becomes unusable.

A better structure would be:

  1. Each client has its own process, with the server process on the left and the mm on the right.
  2. Any error is propagated to the client process, so that's the only thing that dies and whatever was handling it rolls back its state one iteration.
  3. Proper shutdown of the old AllonetPort and respawning of the new, so that new connections can come in

Room state preservation

When the server crashes, it should be able to restart back to the same state.

  1. Serialize the whole room state very frequently
  2. Even serialize the state of connected clients, and client-entity relationships
  3. When restarting from crash, wait for each client to reconnect, and using the public key, reassociate them with their owned entities
  4. Only if they don't reconnect in time, destroy their entities.
Fund with Polar

_Spawn_ interaction

Interaction: ["spawn", Position, [Components, ...]]

Spawns an entity that is owned by the calling client.

Provisional network protocol

I sat down with the visor once and looked at the different network classes... I've already built a network engine on TCP thinking I'd switch it to UDP, but never getting around to that and tcp for gamedev SuuuUUUUUCKS so I was hoping to do UDP off the bat. but building your own reliable comms over UDP is harddd and I don't want to do it myself, so I looked into unity's built in networking classes and found their "reliable udp" proto LLAPI aka NetworkTransport aka UNet. It's open source but only C# and seems a bit over engineered so I did NOT want to implement it from scratch. And then I gave up.... In the best of worlds I would like to use a tiny C webrtc library on both client and server side; but there isn't one. I would use RakNet if it wasn't dead. But it might still be usable...

Access control

Intents and state transmission are out of scope of access control. They're sent as-is.

Interactions however are guarded by access control.

So "interaction requests" are basically Erlang lists. The idea is to make a list of guard clauses which gate entities from calling specific interactions on other entities. The placeserv is the gateway for all interaction requests, so it can hold this list of rules and thus enforce security throughout the room.

So, each entry in the list has:

  1. A guard clause for the interaction expression. Example: ["spawn_entity", X, Y, Z, EDesc] where X > 0
  2. A guard clause for the sender (both entity and client identity)
  3. A guard clause for the receiver
Fund with Polar

Room building appliance

Create a built-in appliance that is ACL'd to the room owner, and allows the owner to decorate and build the room!

It should spawn an entity that has buttons for spawning room geometry, manipulating it, locking and unlocking it, and destroying it.

I think static room geometry is going to have to be entities for now?? Don't know of a better way to represent them. So they'll be entities not owned by a client, but by the room itself.

Spawn apps with URLs

If a user opens an alloappliance+http(s)://..., it should be opened by the visor. The visor should then send an interaction to the placeserv, asking it to spawn the given appliance.

The placeserv should then make the http(s) call to the given URL with a connection instruction json blob:

{ "url": "alloplace://hostname:port", "onBehalfOf": (client identity), "query": (query params as-is from the alloappliance url) }.

The http server receiving this request should then spawn a process for this and connect it to the given room.

Fund with Polar

Make alloplaceserv use allonet

Right now, I've written a dummy C server inside the allonet repo that I use for basic testing. However, I really still want to use the erlang/elixir server, for reliability and expressibility.

So, figure out how to get allonet into Elixir. I was considering for a while if maybe allonet is just a bad abstraction for the server and we should implement an elixir enet client instead, and just use allonet for client-side networking. However, with physics probably ending up inside allonet, I'm rejecting this idea.

Let's try to find a way to get allonet into placeserv in a way that works well with mm's and reliability; and especially which can express the iterative state in an erlang-native manner. This'll be much easier to work with once we want to do state diffing, rollbacks, etc.

Git clone requires --recursive option

Unsure if this is documented anywhere, but an unintuitive step needed to get the project to run is to use the recursive flag when cloning.

git clone --recursive https://github.com/alloverse/alloplace.git

This is necessary because there are submodules.

This is the error that results if you don't do this:

CMake Error at CMakeLists.txt:4 (add_subdirectory):
  The source directory

    /home/username/alloplace/src/allonet

  does not contain a CMakeLists.txt file.


-- Using Erlang OTP: /usr/lib/erlang - found OTP version 21
-- Using erl_interface version: /usr/lib/erlang/lib/erl_interface-3.11.1
-- Using erts version: erts-10.3.1
ei
-- Configuring incomplete, errors occurred!
See also "/home/username/alloplace/_cmake/CMakeFiles/CMakeOutput.log".

make: *** No rule to make target 'all'.  Stop.

Compiling 7 files (.ex)
Generated allo_placeserv app

20:47:42.000 [info]  Starting Alloverse Place server
sh: /home/username/alloplace/priv/AllonetPort: No such file or directory

20:47:47.010 [info]  Application allo_placeserv exited: AlloPlaceserv.Application.start(:normal, []) returned an error: shutdown: failed to start child: AlloPlaceserv.Server
    ** (EXIT) exited in: GenServer.call(#PID<0.439.0>, {:ccall, :ping, {}}, 5000)
        ** (EXIT) time out
** (Mix) Could not start application allo_placeserv: AlloPlaceserv.Application.start(:normal, []) returned an error: shutdown: failed to start child: AlloPlaceserv.Server
    ** (EXIT) exited in: GenServer.call(#PID<0.439.0>, {:ccall, :ping, {}}, 5000)
        ** (EXIT) time out

Hope that helps the next person to encounter this.

Fund with Polar

Add request timeouts

I'm thinking this could be server side rather than client side. An additional field on the 'request' wire protocol, with timeout in seconds as float.

Then, alloplace can determine if:

  • there is no receiver for the request? then immediately signal failure
  • If no response comes through from the receiver within timeout? Signal failure. Then discard response once it comes through (if it does).

Failure signal could look like:

[hd(body), failed, "desc"]

Fund with Polar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.