skeleton for the rewrite

This commit is contained in:
Yessiest 2024-05-11 17:28:45 +04:00
parent abe6521fd6
commit 2dddb0dc89
6 changed files with 5843 additions and 0 deletions

2
.bundle/config Normal file
View File

@ -0,0 +1,2 @@
---
BUNDLE_PATH: ".gems"

5623
.rubocop.yml Normal file

File diff suppressed because it is too large Load Diff

23
.solargraph.yml Normal file
View File

@ -0,0 +1,23 @@
---
include:
- "**/*.rb"
exclude:
- spec/**/*
- test/**/*
- vendor/**/*
- ".bundle/**/*"
require: []
domains: []
reporters:
- rubocop
- require_not_found
- typecheck:typed
formatter:
rubocop:
cops: safe
except: []
only: []
extra_args: []
require_paths: []
plugins: []
max_files: 5000

7
Gemfile Normal file
View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
source "https://rubygems.org"
gem 'websocket'
gem 'landline'
gem 'puma'

124
proto.rb Normal file
View File

@ -0,0 +1,124 @@
# frozen_string_literal: true
module Heimdall
# Container for any uniquely identifiable object
# @abstract
class UUIDObject
UUIDSYM = (('0'..'9').to_a + ('a'..'f').to_a).freeze
class << self
# Add uuids to subclass
def inherited(subclass)
@uuids ||= {}
@foreign_ids ||= {}
@last ||= 0
super(subclass)
subclass.uuids = @uuids
subclass.foreign_ids = @foreign_ids
end
# Create a new UUIDObject with unique UUID
# @return [self]
def new
object = super
@uuids[object.uuid] = object
@last = object.uuid
@foreign_ids[object.foreign_id] = object if object.foreign_id
object
end
# Get object by UUID
# @param uuid
# @return [self, nil]
def get(uuid)
@uuids[uuid] if @uuids[uuid].is_a? self
end
# Get object by foreign id
# @param foreign_id
# @return [self, nil]
def get_foreign(foreign_id)
@foreign_ids[foreign_id] if @foreign_ids[foreign_id].is_a? self
end
attr_accessor :uuids, :foreign_ids, :last
end
def initialize
@uuid = __gen_uuid
@foreign_ids = []
end
attr_reader :uuid, :foreign_id
private
def __gen_uuid
newuuid = (Time.now.to_f * 1000).to_i * 10000
if (self.class.last / 1000) == (newuuid / 1000)
newuuid += (self.class.last % 1000) + 1
end
newuuid
end
end
# PubSub abstract container
# @abstract
class PubSub
def initialize(buffer_size: 1024)
@buffer_size = buffer_size
@listeners = []
@messages = []
end
# Push message to all listeners
# @param msg [UUIDObject]
# @return [void]
def push(msg)
@listeners.each { |x| x.call(msg) }
@messages.append(msg)
@messages.shift if @messages.length > @buffer_size
end
# Add a listener to the PubSub
# @param listener [#call]
# @return [void]
def listen(listener)
@listeners.append(listener)
end
# Pull all messages since UUID
# @param uuid [String]
# @return [Array<UUIDObject>]
def pull(uuid)
output = []
@messages.reverse_each do |x|
break if x.uuid < uuid
output.unshift(x)
end
output
end
end
# Message struct
class Message < UUIDObject
def initialize(datahash, **params)
super(**params)
@from = UUIDObject.get(datahash["from"])
@to = UUIDObject.get(datahash["to"])
@content = datahash["content"]
# @reply_to = datahash["reply_to"] # TODO: make this make sense
@attachments = datahash["attachments"]
end
attr_reader :from, :to, :content, :reply_to, :attachments
end
# User struct
class User < UUIDObject
def initialize(datahash, **params)
super(**params)
@id = datahash["id"]
end

64
server.ru Normal file
View File

@ -0,0 +1,64 @@
# frozen_string_literal: true
require_relative '.env'
require_relative 'proto'
require 'landline'
require 'json'
# Primary server class
class HeimdallServer < Landline::App
before do
# Match data type against a list of datatypes
# @param obj [Object]
# @param type [Array, Class]
def match_type(obj, type)
if type.is_a? Array
type.any? { |t| obj.is_a? t }
else
obj.is_a? type
end
end
# Validate json body for a post request
# @param args [Hash] hash of key - type pairs to check JSON data against
def validate_json(**args)
die(400, backtrace: ['JSON body expected']) unless json?
data = begin
JSON.parse(request.body)
rescue StandardError
die(400, backtrace: ['JSON body is invalid'])
end
args.each do |k, v|
unless data.include?(k) and match_type(data[k], v)
die(400, backtrace: ["Key #{k} is missing"])
end
end
end
end
filter do
request.cookies["token"] == BOT_TOKEN
end
path "/user" do
post "/register" do
validate_json("id" => Integer,
"username" => String,
"nickname" => [String, NilClass])
end
end
handle do |status, backtrace: nil|
page = JSON.dump({
"error" => backtrace.join("\n"),
"code" => status
})
[{
"content-length": page.bytesize,
"content-type": "application/json"
}, page]
end
end
run HeimdallServer.new