Skip to content
This repository was archived by the owner on Apr 27, 2019. It is now read-only.

Commit b0545b3

Browse files
committed
Version 1.2.1:
* Plugin state is now saved; MOTD settings in existing plugins will have to be deleted and replaced after first run. * Starbound configuration manager assures that the settings for the server are correct before running. It can be disabled. * Added /list_players and /delete_player commands. Supports wildcards. * Unicode MOTD support. Errata: Reformatted a bunch of files. Restructured plugin storage.
1 parent ea7ff43 commit b0545b3

17 files changed

Lines changed: 128 additions & 64 deletions

File tree

base_plugin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ class BasePlugin(object):
2121
depends = []
2222
auto_activate = True
2323

24+
def __init__(self):
25+
plugin_config = self.config.plugin_config
26+
if 'auto_activate' not in plugin_config:
27+
plugin_config['auto_activate'] = self.auto_activate
28+
self.config.plugin_config = plugin_config
29+
2430
def activate(self):
2531
"""
2632
Called when the plugins are activated, do any setup work here.

config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ def __getattr__(self, item):
8080
self.logger.error("Couldn't find configuration option %s in configuration file.", item)
8181
raise AttributeError
8282

83+
8384
def __setattr__(self, key, value):
8485
if key == "config":
8586
super(ConfigurationManager, self).__setattr__(key, value)
8687
elif key == "plugin_config":
8788
caller = inspect.stack()[1][0].f_locals["self"].__class__.name
88-
8989
self.config["plugin_config"][caller] = value
9090
else:
9191
self.config[key] = value

config/config.json.default

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,34 @@
1515
"logging_format_console": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
1616
"logging_format_debugfile": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
1717
"logging_format_logfile": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
18-
"owner_uuid": "!!--REPLACE THIS--!!",
18+
"owner_uuid": "b07dbd8c1a681d71ef728161976b6fa5",
1919
"passthrough": false,
2020
"player_db": "config/player.db",
2121
"plugin_config": {
22-
"motd_plugin": "Welcome to the server! Play nice.",
22+
"admin_messenger": {
23+
"auto_activate": true
24+
},
25+
"announcer_plugin": {
26+
"auto_activate": true
27+
},
28+
"bouncer": {
29+
"auto_activate": false
30+
},
31+
"chat_logger": {
32+
"auto_activate": true
33+
},
34+
"command_dispatcher": {
35+
"auto_activate": true
36+
},
37+
"motd_plugin": {
38+
"auto_activate": true,
39+
"motd": "Welcome to the server! Play nice."
40+
},
41+
"mute_manager": {
42+
"auto_activate": true
43+
},
2344
"new_player_greeter_plugin": {
45+
"auto_activate": true,
2446
"items": [
2547
[
2648
"coalore",
@@ -34,6 +56,7 @@
3456
"message": "Welcome to the server! Here are some starter items to get you off to a good start."
3557
},
3658
"planet_protect": {
59+
"auto_activate": true,
3760
"blacklist": [
3861
"bomb",
3962
"bombblockexplosion",
@@ -111,10 +134,23 @@
111134
"protected_planets": []
112135
},
113136
"player_manager": {
137+
"auto_activate": true,
114138
"name_removal_regexes": [
115139
"\\^#[\\w]+;",
116140
"[^ \\w]+"
117141
]
142+
},
143+
"plugin_manager": {
144+
"auto_activate": true
145+
},
146+
"starbound_config_manager": {
147+
"auto_activate": true
148+
},
149+
"user_management_commands": {
150+
"auto_activate": true
151+
},
152+
"warpy_plugin": {
153+
"auto_activate": true
118154
}
119155
},
120156
"plugin_path": "plugins",

plugin_manager.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ class MissingDependency(PluginNotFound):
3131
of a plugin.
3232
"""
3333

34+
3435
class UnresolvedOrCircularDependencyError(Exception):
3536
"""
3637
Raised whenever there is a circular dependency detected in the loading of of plugins.
3738
"""
3839

40+
3941
class PluginManager(object):
4042
logger = logging.getLogger('starrypy.plugin_manager.PluginManager')
4143

@@ -79,7 +81,8 @@ def load_plugins(self, plugin_dir):
7981
try:
8082
mod = __import__(name, globals(), locals(), [], 0)
8183
for _, plugin in inspect.getmembers(mod, inspect.isclass):
82-
if issubclass(plugin, self.base_class) and plugin is not self.base_class and plugin not in seen_plugins:
84+
if issubclass(plugin,
85+
self.base_class) and plugin is not self.base_class and plugin not in seen_plugins:
8386
plugin.config = self.config
8487
plugin.factory = self.factory
8588
plugin.active = False
@@ -92,21 +95,22 @@ def load_plugins(self, plugin_dir):
9295
self.logger.critical("Import error for %s", name)
9396
sys.exit()
9497
try:
95-
dependencies = {x.name:set(x.depends) for x in seen_plugins}
96-
classes = {x.name:x for x in seen_plugins}
98+
dependencies = {x.name: set(x.depends) for x in seen_plugins}
99+
classes = {x.name: x for x in seen_plugins}
97100
while len(dependencies) > 0:
98101
ready = [x for x, d in dependencies.iteritems() if len(d) == 0]
99102
if len(ready) == 0:
100103
ex = []
101104
for n, d in dependencies.iteritems():
102105
for dep in d:
103106
ex.append("%s->%s" % (n, dep))
104-
raise UnresolvedOrCircularDependencyError("Unresolved or circular dependencies found:\n%s" % "\n".join(ex))
107+
raise UnresolvedOrCircularDependencyError(
108+
"Unresolved or circular dependencies found:\n%s" % "\n".join(ex))
105109
for name in ready:
106110
self.plugins[name] = classes[name]()
107111
self.load_order.append(name)
108112
self.logger.debug("Instantiated plugin '%s'" % name)
109-
del(dependencies[name])
113+
del (dependencies[name])
110114
for name, depends in dependencies.iteritems():
111115
to_load = depends & set(self.plugins.iterkeys())
112116
dependencies[name] = dependencies[name].difference(set(self.plugins.iterkeys()))
@@ -132,7 +136,7 @@ def reload_plugins(self):
132136

133137
def activate_plugins(self):
134138
for plugin in [self.plugins[x] for x in self.load_order]:
135-
if plugin.auto_activate:
139+
if self.config.config['plugin_config'][plugin.name]['auto_activate']:
136140
try:
137141
plugin.activate()
138142
except FatalPluginError as e:

plugins/admin_messenger/admin_messenger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ def message_admins(self, message):
3636
def broadcast_message(self, message):
3737
for protocol in self.factory.protocols.itervalues():
3838
protocol.send_chat_message("%sSERVER BROADCAST: %s%s" % (
39-
self.config.colors["admin"], message.message[3:], self.config.colors["default"]))
39+
self.config.colors["admin"], message.message[3:], self.config.colors["default"]))
4040
self.logger.info("Broadcast from %s. Message: %s", self.protocol.player.name,
4141
message.message[3:])

plugins/chat_logger/chat_logger.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
class ChatLogger(BasePlugin):
66
name = "chat_logger"
7+
78
def on_chat_sent(self, data):
89
parsed = chat_sent().parse(data.data)
910
parsed.message = parsed.message.decode("utf-8")

plugins/core/admin_commands_plugin/admin_command_plugin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def make_guest(self, player):
9393
except:
9494
self.player_manager.session.rollback()
9595
raise
96+
9697
@permissions(UserLevels.MODERATOR)
9798
def make_registered(self, player):
9899
player.access_level = UserLevels.REGISTERED
@@ -178,7 +179,8 @@ def give_item(self, data):
178179
self.protocol.send_chat_message("Please check your syntax. %s" % str(e))
179180
return
180181
except AttributeError:
181-
self.protocol.send_chat_message("Please check that the username you are referencing exists. If it has spaces, please surround it by quotes.")
182+
self.protocol.send_chat_message(
183+
"Please check that the username you are referencing exists. If it has spaces, please surround it by quotes.")
182184
return
183185
except:
184186
self.protocol.send_chat_message("An unknown error occured. %s" % str(e))

plugins/core/player_manager/manager.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,10 @@ def __delitem__(self, key):
8787
dict.__delitem__(self, key)
8888
self.changed()
8989

90+
9091
MutableDict.associate_with(JSONEncodedDict)
9192

93+
9294
class Player(Base):
9395
__tablename__ = 'players'
9496

plugins/core/player_manager/plugin.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
class PlayerManagerPlugin(SimpleCommandPlugin):
1515
name = "player_manager"
1616
commands = ["list_players", "delete_player"]
17+
1718
def activate(self):
1819
super(PlayerManagerPlugin, self).activate()
1920
self.player_manager = PlayerManager(self.config)
@@ -47,7 +48,8 @@ def on_client_connect(self, data):
4748
protocol=self.protocol.id)
4849
return True
4950
except AlreadyLoggedIn:
50-
self.reject_with_reason("You're already logged in! If this is not the case, please wait 10 seconds and try again.")
51+
self.reject_with_reason(
52+
"You're already logged in! If this is not the case, please wait 10 seconds and try again.")
5153
self.logger.info("Already logged in user tried to log in.")
5254
except Banned:
5355
self.reject_with_reason("You have been banned!")
@@ -106,12 +108,14 @@ def on_client_disconnect(self, player):
106108
def delete_player(self, data):
107109
name = " ".join(data)
108110
if self.player_manager.get_logged_in_by_name(name) is not None:
109-
self.protocol.send_chat_message("That player is currently logged in. Refusing to delete logged in character.")
111+
self.protocol.send_chat_message(
112+
"That player is currently logged in. Refusing to delete logged in character.")
110113
return False
111114
else:
112115
player = self.player_manager.get_by_name(name)
113116
if player is None:
114-
self.protocol.send_chat_message("Couldn't find a player named %s. Please check the spelling and try again." % name)
117+
self.protocol.send_chat_message(
118+
"Couldn't find a player named %s. Please check the spelling and try again." % name)
115119
return False
116120
self.player_manager.session.delete(player)
117121
self.protocol.send_chat_message("Deleted player with name %s." % name)
@@ -122,11 +126,16 @@ def list_players(self, data):
122126
self.format_player_response(self.player_manager.session.query(Player).all())
123127
else:
124128
rx = re.sub(r"[\*]", "%", " ".join(data))
125-
self.format_player_response(self.player_manager.session.query(Player).filter(Player.name.like(rx)).all())
129+
self.format_player_response(
130+
self.player_manager.session.query(Player).filter(Player.name.like(rx)).all())
126131

127132
def format_player_response(self, players):
128133
if len(players) <= 25:
129-
self.protocol.send_chat_message("Results: %s" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players]))
134+
self.protocol.send_chat_message(
135+
"Results: %s" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players]))
130136
else:
131-
self.protocol.send_chat_message("Results: %s" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players[:25]]))
132-
self.protocol.send_chat_message("And %d more. Narrow it down with SQL like syntax. Feel free to use a *, it will be replaced appropriately." % (len(players) - 25))
137+
self.protocol.send_chat_message(
138+
"Results: %s" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players[:25]]))
139+
self.protocol.send_chat_message(
140+
"And %d more. Narrow it down with SQL like syntax. Feel free to use a *, it will be replaced appropriately." % (
141+
len(players) - 25))
Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,40 @@
1+
import json
12
import os
2-
from base_plugin import BasePlugin
3+
from base_plugin import SimpleCommandPlugin
34
from plugin_manager import FatalPluginError
5+
from plugins.core import permissions, UserLevels
46

5-
class StarboundConfigManager(BasePlugin):
7+
8+
class StarboundConfigManager(SimpleCommandPlugin):
69
name = "starbound_config_manager"
10+
depends = ['command_dispatcher', 'warpy_plugin']
11+
commands = ["spawn"]
712

813
def activate(self):
914
super(StarboundConfigManager, self).activate()
1015
try:
1116
configuration_file = os.path.join(self.config.starbound_path, "starbound.config")
1217
if not os.path.exists(configuration_file):
13-
raise FatalPluginError("Could not open starbound configuration file. Tried path: %s" % configuration_file)
18+
raise FatalPluginError(
19+
"Could not open starbound configuration file. Tried path: %s" % configuration_file)
1420
except AttributeError:
1521
raise FatalPluginError("The starbound path (starbound_path) is not set in the configuration.")
22+
try:
23+
with open(configuration_file, "r") as f:
24+
starbound_config = json.load(f)
25+
except Exception as e:
26+
raise FatalPluginError(
27+
"Could not parse the starbound configuration file as JSON. Error given from JSON decoder: %s" % str(
28+
e))
29+
if self.config.upstream_port != starbound_config['gamePort']:
30+
raise FatalPluginError(
31+
"The starbound gamePort option (%d) does not match the config.json value (%d)." % (
32+
starbound_config['gamePort'], self.config.upstream_port))
33+
self._spawn = starbound_config['defaultWorldCoordinate'].split(":")
1634

35+
@permissions(UserLevels.GUEST)
36+
def spawn(self, data):
37+
"""Warps you to spawn. Syntax: /spawn"""
38+
self.plugins['warpy_plugin'].move_player_ship(self.protocol, self._spawn)
39+
self.protocol.send_chat_message("Moving your ship to spawn.")
1740

0 commit comments

Comments
 (0)