def parse(self, string): """Parses a dicecloud-formatted string (evaluating text in {}).""" try: return re.sub(r'(?<!\\){(.+?)}', lambda m: str(self.eval(m.group(1))), string) except Exception as ex: raise EvaluationError(ex, string)
def evalrepl(match): try: if match.group('lookup'): # <> if re.match(r'<a?([@#]|:.+:)[&!]{0,2}\d+>', match.group(0)): # ignore mentions return match.group(0) out = match.group('lookup') evalresult = str(self.names.get(out, out)) elif match.group('roll'): # {} varstr = match.group('roll') curlyout = "" for substr in re.split(ops, varstr): temp = substr.strip() curlyout += str(self.names.get(temp, temp)) + " " try: evalresult = str(self._limited_roll(curlyout)) except: evalresult = '0' elif match.group('drac1'): # {{}} evalresult = self.eval(match.group('drac1').strip()) elif match.group('drac2'): # <drac2>...</drac2> evalresult = self.execute(match.group('drac2').strip()) else: evalresult = None except Exception as ex: raise EvaluationError(ex, match.group(0)) return str(evalresult) if evalresult is not None else ''
def evalrepl(match): try: if match.group(1): # {{}} double_func = double_curly or self.eval evalresult = double_func(match.group(1)) elif match.group(2): # <> if re.match(r'<a?([@#]|:.+:)[&!]{0,2}\d+>', match.group(0)): # ignore mentions return match.group(0) out = match.group(2) ltgt_func = ltgt or (lambda s: str(self.names.get(s, s))) evalresult = ltgt_func(out) elif match.group(3): # {} varstr = match.group(3) def default_curly_func(s): curlyout = "" for substr in re.split(ops, s): temp = substr.strip() curlyout += str(self.names.get(temp, temp)) + " " return str(roll(curlyout).total) curly_func = curly or default_curly_func evalresult = curly_func(varstr) else: evalresult = None except Exception as ex: raise EvaluationError(ex, match.group(0)) return str(evalresult) if evalresult is not None else ''
def parse(self, string, extra_names=None): """Parses a spell-formatted string (evaluating {{}} and replacing {} with rollstrings).""" original_names = None if extra_names: original_names = self.names.copy() self.names.update(extra_names) def evalrepl(match): if match.group(1): # {{}} evalresult = self.eval(match.group(1)) elif match.group(3): # {} evalresult = self.names.get(match.group(3), match.group(0)) else: evalresult = None return str(evalresult) if evalresult is not None else '' try: output = re.sub(SCRIPTING_RE, evalrepl, string) # evaluate except Exception as ex: raise EvaluationError(ex) if original_names: self.names = original_names return output
def process(to_process): ops = r"([-+*/().<>=])" user_vars = ctx.bot.db.jhget("user_vars", ctx.message.author.id, {}) if ctx else {} _vars = user_vars global_vars = None # we'll load them if we need them evaluator = self.nochar_eval evaluator.reset() def get_gvar(name): nonlocal global_vars if global_vars is None: # load only if needed global_vars = ctx.bot.db.jget("global_vars", {}) return global_vars.get(name, {}).get('value') def exists(name): return name in evaluator.names evaluator.functions['get_gvar'] = get_gvar evaluator.functions['exists'] = exists def set_value(name, value): evaluator.names[name] = value return '' evaluator.functions['set'] = set_value evaluator.names.update(_vars) def evalrepl(match): if match.group(1): # {{}} evalresult = evaluator.eval(match.group(1)) elif match.group(2): # <> if re.match(r'<a?([@#]|:.+:)[&!]{0,2}\d+>', match.group(0)): # ignore mentions return match.group(0) out = match.group(2) evalresult = str(_vars.get(out, out)) elif match.group(3): # {} varstr = match.group(3) out = "" for substr in re.split(ops, varstr): temp = substr.strip() out += str(_vars.get(temp, temp)) + " " evalresult = str(roll(out).total) else: evalresult = None return str(evalresult) if evalresult is not None else '' try: output = re.sub(SCRIPTING_RE, evalrepl, to_process) # evaluate except Exception as ex: raise EvaluationError(ex) return output
def evalrepl(match): try: if match.group(1): # {{}} evalresult = self.eval(match.group(1)) elif match.group(3): # {} evalresult = self.names.get(match.group(3), match.group(0)) else: evalresult = None except Exception as ex: raise EvaluationError(ex, match.group(0)) return str(evalresult) if evalresult is not None else ''
def parse_annostr(self, annostr, is_full_expression=False): if not is_full_expression: return self.evaluator.parse(annostr, extra_names=self.metavars) original_names = self.evaluator.names.copy() self.evaluator.names.update(self.metavars) try: out = self.evaluator.eval(annostr) except Exception as ex: raise EvaluationError(ex, annostr) self.evaluator.names = original_names return out
def process(to_process): ops = r"([-+*/().<>=])" _vars = user_vars evaluator = self.nochar_eval evaluator.reset() def get_gvar(name): if name not in _cache['gvars']: result = ctx.bot.mdb.gvars.delegate.find_one({"key": name}) if result is None: return None _cache['gvars'][name] = result['value'] return _cache['gvars'][name] def exists(name): return name in evaluator.names evaluator.functions['get_gvar'] = get_gvar evaluator.functions['exists'] = exists def set_value(name, value): evaluator.names[name] = value return '' evaluator.functions['set'] = set_value evaluator.names.update(_vars) def evalrepl(match): if match.group(1): # {{}} evalresult = evaluator.eval(match.group(1)) elif match.group(2): # <> if re.match(r'<a?([@#]|:.+:)[&!]{0,2}\d+>', match.group(0)): # ignore mentions return match.group(0) out = match.group(2) evalresult = str(_vars.get(out, out)) elif match.group(3): # {} varstr = match.group(3) out = "" for substr in re.split(ops, varstr): temp = substr.strip() out += str(_vars.get(temp, temp)) + " " evalresult = str(roll(out).total) else: evalresult = None return str(evalresult) if evalresult is not None else '' try: output = re.sub(SCRIPTING_RE, evalrepl, to_process) # evaluate except Exception as ex: raise EvaluationError(ex) return output
def evalrepl(match): try: if match.group('drac1'): # {{}} evalresult = self.eval(match.group('drac1').strip()) elif match.group('roll'): # {} try: evalresult = self.eval(match.group('roll').strip()) except: evalresult = match.group(0) else: evalresult = None except Exception as ex: raise EvaluationError(ex, match.group(0)) return str(evalresult) if evalresult is not None else ''
def parse(self, string, double_curly=None, curly=None, ltgt=None): """Parses a scripting string (evaluating text in {{}}).""" ops = r"([-+*/().<>=])" def evalrepl(match): if match.group(1): # {{}} double_func = double_curly or self.eval evalresult = double_func(match.group(1)) elif match.group(2): # <> if re.match(r'<a?([@#]|:.+:)[&!]{0,2}\d+>', match.group(0)): # ignore mentions return match.group(0) out = match.group(2) ltgt_func = ltgt or (lambda s: str(self.names.get(s, s))) evalresult = ltgt_func(out) elif match.group(3): # {} varstr = match.group(3) def default_curly_func(s): curlyout = "" for substr in re.split(ops, s): temp = substr.strip() curlyout += str(self.names.get(temp, temp)) + " " return str(roll(curlyout).total) curly_func = curly or default_curly_func evalresult = curly_func(varstr) else: evalresult = None return str(evalresult) if evalresult is not None else '' try: output = re.sub(SCRIPTING_RE, evalrepl, string) # evaluate except Exception as ex: raise EvaluationError(ex) return output
def process(to_process): character = self.character ops = r"([-+*/().<>=])" cvars = character.get('cvars', {}) stat_vars = character.get('stat_cvars', {}) stat_vars['color'] = hex(self.get_color())[2:] _vars = user_vars _vars.update(cvars) # define our weird functions here def get_cc(name): return self.get_consumable_value(name) def get_cc_max(name): return self.evaluate_cvar( self.get_consumable(name).get('max', str(2**32 - 1))) def get_cc_min(name): return self.evaluate_cvar( self.get_consumable(name).get('min', str(-(2**32)))) def set_cc(name, value: int, strict=False): self.set_consumable(name, value, strict) nonlocal changed changed = True def mod_cc(name, val: int, strict=False): return set_cc(name, get_cc(name) + val, strict) def delete_cc(name): self.delete_consumable(name) nonlocal changed changed = True def create_cc_nx(name: str, minVal: str = None, maxVal: str = None, reset: str = None, dispType: str = None): if not name in self.get_all_consumables(): self.create_consumable(name, minValue=minVal, maxValue=maxVal, reset=reset, displayType=dispType) nonlocal changed changed = True def cc_exists(name): return name in self.get_all_consumables() def cc_str(name): counter = self.get_consumable(name) _max = counter.get('max') val = str(counter.get('value', 0)) if counter.get('type') == 'bubble': if _max is not None: _max = self.evaluate_cvar(_max) numEmpty = _max - counter.get('value', 0) filled = '\u25c9' * counter.get('value', 0) empty = '\u3007' * numEmpty val = f"{filled}{empty}" else: if _max is not None: _max = self.evaluate_cvar(_max) val = f"{counter.get('value')} / {_max}" return val def get_slots(level: int): return self.get_remaining_slots(level) def get_slots_max(level: int): return self.get_max_spellslots(level) def slots_str(level: int): return self.get_remaining_slots_str(level).strip() def set_slots(level: int, value: int): self.set_remaining_slots(level, value) nonlocal changed changed = True def use_slot(level: int): self.use_slot(level) nonlocal changed changed = True def get_hp(): return self.get_current_hp() - self.get_temp_hp() def set_hp(val: int): self.set_hp(val, True) nonlocal changed changed = True def mod_hp(val: int, overflow: bool = True): if not overflow: return set_hp( min(self.get_current_hp() + val, self.get_max_hp())) else: return set_hp(self.get_current_hp() + val) def get_temphp(): return self.get_temp_hp() def set_temphp(val: int): self.set_temp_hp(val) nonlocal changed changed = True def set_cvar(name, val: str): self.set_cvar(name, val) _names[name] = str(val) nonlocal changed changed = True def set_cvar_nx(name, val: str): if not name in self.get_cvars(): set_cvar(name, val) def delete_cvar(name): if name in self.get_cvars(): del self.get_cvars()[name] nonlocal changed changed = True def get_gvar(name): if name not in _cache['gvars']: result = ctx.bot.mdb.gvars.delegate.find_one({"key": name}) if result is None: return None _cache['gvars'][name] = result['value'] return _cache['gvars'][name] def exists(name): return name in evaluator.names def get_raw(): return copy.copy(self.character) def combat(): nonlocal commit_combat commit_combat = True return _cache['combat'] _funcs = scripting.DEFAULT_FUNCTIONS.copy() _funcs.update(get_cc=get_cc, set_cc=set_cc, get_cc_max=get_cc_max, get_cc_min=get_cc_min, mod_cc=mod_cc, delete_cc=delete_cc, cc_exists=cc_exists, create_cc_nx=create_cc_nx, cc_str=cc_str, get_slots=get_slots, get_slots_max=get_slots_max, set_slots=set_slots, use_slot=use_slot, slots_str=slots_str, get_hp=get_hp, set_hp=set_hp, mod_hp=mod_hp, get_temphp=get_temphp, set_temphp=set_temphp, set_cvar=set_cvar, delete_cvar=delete_cvar, set_cvar_nx=set_cvar_nx, get_gvar=get_gvar, exists=exists, get_raw=get_raw, combat=combat) _ops = scripting.DEFAULT_OPERATORS.copy() _names = copy.copy(_vars) _names.update(stat_vars) _names.update({ "True": True, "False": False, "currentHp": self.get_current_hp() }) evaluator = ScriptingEvaluator(functions=_funcs, operators=_ops, names=_names) def set_value(name, value): evaluator.names[name] = value evaluator.functions['set'] = set_value def evalrepl(match): if match.group(1): # {{}} evalresult = evaluator.eval(match.group(1)) elif match.group(2): # <> if re.match(r'<a?([@#]|:.+:)[&!]{0,2}\d+>', match.group(0)): # ignore mentions return match.group(0) out = match.group(2) if out.startswith('/'): _last = character for path in out.split('/'): if path: try: _last = _last.get(path, {}) except AttributeError: break out = str(_last) out = str(_vars.get(out, out)) evalresult = str(stat_vars.get(out, out)) elif match.group(3): # {} varstr = match.group(3) out = "" tempout = '' for substr in re.split(ops, varstr): temp = substr.strip() tempout += str(_vars.get(temp, temp)) + " " for substr in re.split(ops, tempout): temp = substr.strip() out += str(stat_vars.get(temp, temp)) + " " evalresult = str(roll(out).total) else: evalresult = None return str(evalresult) if evalresult is not None else '' try: output = re.sub(SCRIPTING_RE, evalrepl, to_process) # evaluate except Exception as ex: raise EvaluationError(ex) return output