from helpers import * from java.util.UUID import fromString as juuid import time import thread from traceback import format_exc as trace time_format = "%Y.%m.%d %H:%M" reports = open_json_file("reports", []) check_reports = True check_delay = 60 * 10 # Every 10 minutes, staff will be notified about pending reports. rp_permission = "utils.rp" def print_help(sender): msg(sender, " &2/report &eReport something") msg(sender, " &2/rp open &eList open reports (id, player, text)") msg(sender, " &2/rp closed &eList closed reports (id, player, text)") msg(sender, " &2/rp tp &eTeleport to report's location & show details") msg(sender, " &2/rp close &eResolve an open report") msg(sender, " &2/rp reopen &eReopen a resolved report") msg(sender, " &2/rp del &eDelete a report (admin only)") def print_list(sender, closed): try: # new thread, anything can happen. targeted_reports = dict(enumerate(reports)) for i in list(targeted_reports): report = targeted_reports[i] if report["closed"] != closed: targeted_reports.pop(i) msg(sender, "&a%s %s reports:" % (len(targeted_reports), "closed" if closed else "open")) for i in targeted_reports: report = targeted_reports[i] name = retrieve_player(report["uuid"]).getName() msg(sender, "&8[&e%s &c%s&8] &3%s&f: &a%s" % (i, report["time"], name, report["msg"])) except: warn("Failed to complete report's print_list() thread") error(trace()) def tp_report(sender, rep_id): if rep_id >= len(reports) or rep_id < 0: msg(sender, "&cReport &3#" + str(rep_id) + "&c does not exist!") else: report = reports[rep_id] safetp(sender, server.getWorld(report["world"]), report["x"], report["y"], report["z"], report["yaw"], report["pitch"]) msg(sender, "&aTeleported to %s&areport #%s" % ("&cclosed " if report["closed"] else "", rep_id)) # resolve == True: You're resolving, False: reopening def resolve_reopen_report(sender, rep_id, resolve): action = "resolved" if resolve else "reopened" report = edit_report(sender, rep_id) if report != None: if report["closed"] == resolve: msg(sender, "&cReport &3#%s&c was already %s!" % (rep_id, action)) else: report["closed"] = resolve save_reports() msg(sender, "&aReport #%s %s" % (rep_id, action)) message_reporter(sender, report, action) def delete_report(sender, rep_id): if not sender.hasPermission(rp_permission + ".del"): noperm(sender) return action = "&cdeleted" report = edit_report(sender, rep_id) if report != None: reports.remove(report) save_reports() msg(sender, "&aReport #%s %s" % (rep_id, action)) message_reporter(sender, report, action) def edit_report(sender, rep_id): if len(reports) > rep_id >= 0: return reports[rep_id] msg(sender, "&cThat report does not exist!") return None def message_reporter(sender, report, action): reporter = get_reporter(report) message = "&aReport '&e%s&a' was %s &aby %s." % (report["msg"], action, sender.getName()) if reporter.isOnline(): plugin_header(reporter, "Reports") msg(reporter, message) else: server.dispatchCommand(sender, "mail send %s %s" % (reporter.getName(), colorify(message))) def save_reports(): save_json_file("reports", reports) @hook.command("rp") def on_rp_command(sender, command, label, args): if sender.hasPermission(rp_permission): plugin_header(sender, "Reports") if len(args) > 0: subcmd = args[0].lower() if subcmd == "closed": # needs to run in seperate thread because of getOfflinePlayer thread.start_new_thread(print_list, (sender, True,)) elif subcmd in ["open", "list"]: thread.start_new_thread(print_list, (sender, False,)) else: if not checkargs(sender, args, 2, 2): return True try: repid = int(args[1]) except ValueError: msg(sender, "&cDoesn't look like &3" + args[1] + "&c is a valid number!") print_help(sender) return True if subcmd == "tp": if not is_player(sender): msg(sender, "&conly players can do this") return True tp_report(sender, repid) elif subcmd == "close": resolve_reopen_report(sender, repid, True) elif subcmd == "del": delete_report(sender, repid) elif subcmd == "reopen": resolve_reopen_report(sender, repid, False) else: print_help(sender) else: print_help(sender) else: noperm(sender) return True @hook.command("report") def on_report_command(sender, command, label, args): plugin_header(sender, "Report") if not is_player(sender): msg(sender, "&conly players can do this") return True if not checkargs(sender, args, 1, -1): return True text = " ".join(args) loc = sender.getLocation() reporter = sender.name reporter_id = uid(sender) report = { "uuid": reporter_id, "msg": text, "x": int(loc.x), "y": int(loc.y), "z": int(loc.z), "yaw": int(loc.yaw), "pitch": int(loc.pitch), "world": loc.getWorld().name, "time": time.strftime(time_format), "closed": False } reports.append(report) save_reports() broadcast(rp_permission, "&aReport #" + str(len(reports) -1) + ": " + reporter + "&f: " + text) msg(sender, "&aReported \"&e" + text + "&a\"") return True def reports_reminder(): # needs 2 args for unknown reason while True: for i in range(0, check_delay*2): time.sleep(0.5) # check every 0.5 seconds if we should kill the thread if not check_reports: info("Reports reminder thread killed.") thread.exit() targeted_reports = get_reports(False) if len(targeted_reports) > 0: broadcast(rp_permission, "&aThere are %s open reports!" % len(targeted_reports)) def stop_reporting(): global check_reports info("Ending reports reminder thread") check_reports = False def get_reports(closed): targeted_reports = [] for report in reports: if report["closed"] == closed: targeted_reports.append(report) return targeted_reports def get_reporter(report): return server.getOfflinePlayer(juuid(report["uuid"])) thread.start_new_thread(reports_reminder, ())