Custom attributes for players and plugins

This commit is contained in:
Ben 2020-05-17 03:21:34 +01:00
parent ef2e32c473
commit 4288248864
7 changed files with 108 additions and 1 deletions

View File

@ -722,6 +722,34 @@ COMMENT ON TABLE penguin_permission IS 'Penguin permissions';
COMMENT ON COLUMN penguin_permission.penguin_id IS 'Penguin ID';
COMMENT ON COLUMN penguin_permission.permission_id IS 'Penguin permission ID';
DROP TABLE IF EXISTS penguin_attribute;
CREATE TABLE penguin_attribute (
name TEXT NOT NULL,
penguin_id INT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (name, penguin_id),
CONSTRAINT penguin_attribute_ibfk_1 FOREIGN KEY (penguin_id) REFERENCES penguin(id) ON DELETE CASCADE ON UPDATE CASCADE
);
COMMENT ON TABLE penguin_attribute IS 'Custom penguin attributes';
COMMENT ON COLUMN penguin_attribute.name IS 'Attribute unique identifier';
COMMENT ON COLUMN penguin_attribute.penguin_id IS 'Penguin ID';
COMMENT ON COLUMN penguin_attribute.value IS 'Value of attribute';
DROP TABLE IF EXISTS plugin_attribute;
CREATE TABLE plugin_attribute (
name TEXT NOT NULL,
plugin_name TEXT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (name, plugin_name)
);
COMMENT ON TABLE plugin_attribute IS 'Custom plugin attributes';
COMMENT ON COLUMN plugin_attribute.name IS 'Attribute unique identifier';
COMMENT ON COLUMN plugin_attribute.plugin_name IS 'Name of plugin attribute belongs to';
COMMENT ON COLUMN plugin_attribute.value IS 'Value of attribute';
DROP TABLE IF EXISTS report;
CREATE TABLE report (

View File

@ -114,6 +114,12 @@ class PenguinStringCompiler(OrderedDict):
return getattr(p, attribute_name) or 0
return attribute_method
@classmethod
def custom_attribute_by_name(cls, attribute_name):
async def attribute_method(p):
return p.get_custom_attribute(attribute_name, 0)
return attribute_method
@classmethod
def setup_default_builder(cls, string_builder):
string_builder.update({

View File

@ -84,6 +84,7 @@ class Penguin(db.Model):
def __init__(self, *args, **kwargs):
self.inventory = None
self.permissions = None
self.attributes = None
self.igloos = None
self.igloo_rooms = None
self.furniture = None

30
houdini/data/plugin.py Normal file
View File

@ -0,0 +1,30 @@
from houdini.data import db, AbstractDataCollection
class PluginAttribute(db.Model):
__tablename__ = 'plugin_attribute'
plugin_name = db.Column(db.Text, primary_key=True, nullable=False)
name = db.Column(db.Text, primary_key=True, nullable=False)
value = db.Column(db.Text)
class PenguinAttribute(db.Model):
__tablename__ = 'penguin_attribute'
penguin_id = db.Column(db.ForeignKey('penguin.id', ondelete='CASCADE', onupdate='CASCADE'), primary_key=True,
nullable=False)
name = db.Column(db.Text, primary_key=True, nullable=False)
value = db.Column(db.Text)
class PenguinAttributeCollection(AbstractDataCollection):
__model__ = PenguinAttribute
__indexby__ = 'name'
__filterby__ = 'penguin_id'
class PluginAttributeCollection(AbstractDataCollection):
__model__ = PluginAttribute
__indexby__ = 'name'
__filterby__ = 'plugin_name'

View File

@ -4,6 +4,7 @@ import time
from houdini import handlers
from houdini.data.item import Item, ItemCollection, PenguinItemCollection
from houdini.data.permission import PenguinPermissionCollection
from houdini.data.plugin import PenguinAttributeCollection
from houdini.handlers import Priority, XMLPacket, XTPacket
@ -45,6 +46,7 @@ async def items_load(server):
async def load_inventory(p):
p.inventory = await PenguinItemCollection.get_collection(p.id)
p.permissions = await PenguinPermissionCollection.get_collection(p.id)
p.attributes = await PenguinAttributeCollection.get_collection(p.id)
if p.color is not None and p.color not in p.inventory:
await p.inventory.insert(item_id=p.color)

View File

@ -263,8 +263,28 @@ class Penguin(Spheniscidae, penguin.Penguin):
async def add_permission(self, permission):
if permission not in self.permissions:
await self.permissions.insert(name=permission)
def get_custom_attribute(self, name, default=None):
penguin_attribute = self.attributes.get(name, default)
if penguin_attribute == default:
return default
return penguin_attribute.value
self.logger.info(f'{self.username} was assigned permission \'{permission}\'')
async def set_custom_attribute(self, name, value):
if name not in self.attributes:
await self.attributes.insert(name=name, value=value)
else:
attribute = self.attributes[name]
await attribute.update(value=value).apply()
self.logger.info(f'{self.username} set custom attribute \'{name}\' to \'{value}\'')
return True
async def delete_custom_attribute(self, name):
if name in self.attributes:
await self.attributes.delete(name)
self.logger.info(f'{self.username} deleted attribute \'{name}\'')
return True

View File

@ -2,6 +2,7 @@ import inspect
from abc import ABC, abstractmethod
from houdini import _AbstractManager, get_package_modules
from houdini.data.plugin import PluginAttributeCollection
class IPlugin(ABC):
@ -28,9 +29,27 @@ class IPlugin(ABC):
async def ready(self):
"""Called when the plugin is ready to function."""
def get_attribute(self, name, default=None):
plugin_attribute = self.attributes.get(name, default)
if plugin_attribute == default:
return default
return plugin_attribute.value
async def set_attribute(self, name, value):
if name not in self.attributes:
await self.attributes.insert(name=name, value=value)
else:
plugin_attribute = self.attributes.get(name)
await plugin_attribute.update(value=value).apply()
async def delete_attribute(self, name):
if name in self.attributes:
await self.attributes.delete(name)
@abstractmethod
def __init__(self, server):
self.server = server
self.attributes = None
class PluginManager(_AbstractManager):
@ -58,6 +77,7 @@ class PluginManager(_AbstractManager):
await self.server.xml_listeners.load(plugin_object)
await self.server.dummy_event_listeners.load(plugin_object)
plugin_object.attributes = await PluginAttributeCollection.get_collection(plugin_index)
await plugin_object.ready()