You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
4.5 KiB
221 lines
4.5 KiB
UIDS = {}
|
|
|
|
module Heimdall
|
|
VERSION = "0.99 beta"
|
|
attr_reader :VERSION
|
|
|
|
class ProtocolError < StandardError
|
|
end
|
|
|
|
class UID
|
|
def initialize
|
|
@UID_prefix = "abstract" if not @UID_prefix
|
|
id = (1..32).map { |x| (rand()*10).floor }.join
|
|
while UIDS.has_key? id do
|
|
id = (1..32).map { |x| (rand()*10).floor }.join
|
|
end
|
|
UIDS[@UID_prefix+id] = self
|
|
@UID = id
|
|
end
|
|
attr_reader :UID
|
|
end
|
|
|
|
class UserCache
|
|
def initialize
|
|
@users = {}
|
|
end
|
|
def sync(data)
|
|
data.each { |userdata|
|
|
if not @users[userdata["protocol_id"]] then
|
|
new_user = User.new userdata
|
|
@users[new_user.protoid] = new_user
|
|
else
|
|
@users[userdata["protocol_id"]].modify(userdata)
|
|
end
|
|
}
|
|
end
|
|
def add(user)
|
|
@users[user.protoid] = user
|
|
end
|
|
def get(protoid)
|
|
raise ProtocolError, "user not found" if not @users[protoid]
|
|
return @users[protoid]
|
|
end
|
|
def search(name,n,&block)
|
|
@users.select(&block).take(n)
|
|
end
|
|
def search_by_name(name, n = 10)
|
|
search(name,n) { |k,v| v.username.match? name }
|
|
end
|
|
def search_by_protoid(name,n = 10)
|
|
search(name,n) { |k,v| k.match? name }
|
|
end
|
|
def filter(&block)
|
|
@users.filter &block
|
|
end
|
|
def delete(protoid)
|
|
@users.delete protoid
|
|
end
|
|
def bulk_delete(protoid_list)
|
|
protoid_list.each { |x| @users.delete x }
|
|
end
|
|
end
|
|
|
|
class RoomCache < UserCache
|
|
def get(protoid)
|
|
raise ProtocolError, "room not found" if not @users[protoid]
|
|
return @users[protoid]
|
|
end
|
|
def sync(data)
|
|
data.each { |userdata|
|
|
if not @users[userdata["protocol_id"]] then
|
|
new_user = Room.new userdata
|
|
@users[new_user.protoid] = new_user
|
|
else
|
|
@users[userdata["protocol_id"]].modify(userdata)
|
|
end
|
|
}
|
|
end
|
|
end
|
|
|
|
class RoomFilter
|
|
def initialize(cache, room_protoid)
|
|
@cache = cache
|
|
@filter = room_protoid
|
|
end
|
|
def get(protoid)
|
|
raise ProtocolError, "user not found" if not _filter[protoid]
|
|
return _filter[protoid]
|
|
end
|
|
private
|
|
def _filter
|
|
@cache.filter { |k,v|
|
|
v.protoid == @filter
|
|
}
|
|
end
|
|
end
|
|
|
|
class User < UID
|
|
def initialize(data)
|
|
@username = data["username"]
|
|
@protoid = data["protocol_id"]
|
|
@UID_prefix = "user"
|
|
@channel = DirectChannel.new
|
|
super()
|
|
end
|
|
def to_card()
|
|
return {
|
|
"username" => @username,
|
|
"protoid" => @protoid
|
|
}
|
|
end
|
|
def modify(data)
|
|
@username = data["username"]
|
|
end
|
|
attr_reader :username
|
|
attr_reader :protoid
|
|
attr_reader :channel
|
|
end
|
|
|
|
class Room < UID
|
|
def initialize(data)
|
|
@name = data["name"]
|
|
@protoid = data["protocol_id"]
|
|
@UID_prefix = "room"
|
|
@channel = RoomChannel.new
|
|
@users = {}
|
|
super()
|
|
end
|
|
def to_card()
|
|
return {
|
|
"name" => @name,
|
|
"protoid" => @protoid
|
|
}
|
|
end
|
|
def modify(data)
|
|
@name = data["name"]
|
|
end
|
|
attr_reader :users
|
|
attr_reader :username
|
|
attr_reader :protoid
|
|
attr_reader :channel
|
|
end
|
|
|
|
class Channel < UID
|
|
def initialize
|
|
@UID_prefix = "channel"
|
|
@messages = MsgStack.new
|
|
@read = 0
|
|
super()
|
|
end
|
|
def send(msg)
|
|
@messages.push(msg)
|
|
@read = @read+1
|
|
end
|
|
def send_silent(msg)
|
|
@messages.push(msg)
|
|
end
|
|
def get(n = 1)
|
|
raise Heimdall::ProtocolError, "Invalid number of messages" if n < 0
|
|
return @messages.pull(n)
|
|
end
|
|
def read()
|
|
messages = @messages.pull(@read)
|
|
@read = 0
|
|
return messages
|
|
end
|
|
end
|
|
|
|
class DirectChannel < Channel
|
|
def initialize
|
|
@UID_prefix = "dchannel"
|
|
super()
|
|
end
|
|
end
|
|
|
|
class RoomChannel < Channel
|
|
def initialize
|
|
@UID_prefix = "schannel"
|
|
super()
|
|
end
|
|
undef read
|
|
def get(n = 1)
|
|
@read = 0
|
|
super(n)
|
|
end
|
|
end
|
|
|
|
class Message < UID
|
|
def initialize(data)
|
|
@content = data["content"]
|
|
@from = data["from"]
|
|
@to = data["to"]
|
|
@UID_prefix = "message"
|
|
super()
|
|
end
|
|
def to_struct
|
|
return {
|
|
"content" => @content,
|
|
"from" => @from,
|
|
"to" => @to
|
|
}
|
|
end
|
|
attr_reader :content
|
|
attr_reader :from
|
|
attr_reader :to
|
|
end
|
|
|
|
class MsgStack < UID
|
|
def initialize
|
|
@UID_prefix = "msgstack"
|
|
@messages = []
|
|
super()
|
|
end
|
|
def push(msg)
|
|
@messages.append(msg)
|
|
end
|
|
def pull(n)
|
|
@messages.last n
|
|
end
|
|
end
|
|
end
|