Skip to content

Commit

Permalink
✨ Added some control to the outer event in a listen once section
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsTheSky committed Sep 4, 2024
1 parent de9d2f9 commit 9cc3bf3
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package info.itsthesky.disky.elements.sections.once;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.Variable;
import ch.njol.skript.variables.Variables;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class EffOuterExecution extends Effect {

static {
Skript.registerEffect(
EffOuterExecution.class,
"outer <.+>"
);
}

private SecListenOnce secListenOnce;
private Effect effect;

@Override
public boolean init(Expression<?> @NotNull [] expressions, int matchedPattern, @NotNull Kleenean isDelayed, SkriptParser.@NotNull ParseResult parseResult) {
secListenOnce = getParser().getCurrentSection(SecListenOnce.class);
if (secListenOnce == null) {
Skript.error("The 'outer' effect can only be used in a 'listen once' section.");
return false;
}

final String rawEffect = parseResult.regexes.get(0).group();
return secListenOnce.executeInOuter(() -> {
effect = Effect.parse(rawEffect, "Can't understand this effect: " + rawEffect);
return true;
});
}

@Override
protected void execute(@NotNull Event event) {
effect.run(secListenOnce.getOuterEvent());
}

@Override
public @NotNull String toString(@Nullable Event event, boolean debug) {
return "outer " + effect.toString(event, debug);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package info.itsthesky.disky.elements.sections.once;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.ParseContext;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ExprOuterExpression extends SimpleExpression<Object> {

// static {
// Skript.registerExpression(
// ExprOuterExpression.class,
// Object.class,
// ExpressionType.COMBINED,
// "[the] outer <.+>"
// );
// }

private Expression<?> expr;
private SecListenOnce secListenOnce;

@Override
public boolean init(Expression<?> @NotNull [] exprs, int matchedPattern, @NotNull Kleenean isDelayed, SkriptParser.@NotNull ParseResult parseResult) {
secListenOnce = getParser().getCurrentSection(SecListenOnce.class);
if (secListenOnce == null) {
Skript.error("The 'outer' expression can only be used in a 'listen once' section.");
return false;
}

var rawExpression = parseResult.regexes.get(0).group();
expr = new SkriptParser(rawExpression, SkriptParser.PARSE_LITERALS, ParseContext.DEFAULT).parseExpression(Object.class);
if (expr == null) {
Skript.error("Cannot parse the given expression: " + rawExpression);
return false;
}

return secListenOnce.executeInOuter(() -> expr.init(exprs, matchedPattern, isDelayed, parseResult));
}

@Override
protected Object @NotNull [] get(@NotNull Event event) {
return expr.getArray(secListenOnce.getOuterEvent());
}

@Override
public boolean isSingle() {
return expr.isSingle();
}

@Override
public @NotNull Class<?> getReturnType() {
return expr.getReturnType();
}

@Override
public @NotNull String toString(@Nullable Event event, boolean debug) {
return "the outer " + expr.toString(event, debug);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,70 @@
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.util.Getter;
import ch.njol.skript.util.Utils;
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;
import info.itsthesky.disky.DiSky;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Map;
import java.util.stream.Stream;

@NoDoc
public class ExprSubEventExpression extends WrapperExpression<Object> {

static {
Skript.registerExpression(ExprSubEventExpression.class, Object.class,
ExpressionType.PROPERTY, "[the] event-%*classinfo%");// property so that it is parsed after most other expressions
ExpressionType.PROPERTY, "[the] outer event-%*classinfo%");// property so that it is parsed after most other expressions
}

public SecListenOnce secListenOnce;

@Override
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, @NotNull Kleenean isDelayed, SkriptParser.ParseResult parser) {
secListenOnce = getParser().getCurrentSection(SecListenOnce.class);
if (secListenOnce == null) {
Skript.error("The 'outer event' expression can only be used in a 'listen once' section.");
return false;
}

ClassInfo<?> classInfo = ((Literal<ClassInfo<?>>) exprs[0]).getSingle();
Class<?> c = classInfo.getC();

boolean plural = Utils.getEnglishPlural(parser.expr).getSecond();
EventValueExpression<?> eventValue = new EventValueExpression<>(plural ? CollectionUtils.arrayType(c) : c);
setExpr(eventValue);
return eventValue.init();

var oldEvents = getParser().getCurrentEvents();
getParser().setCurrentEvents(secListenOnce.getCurrentEvents());
DiSky.debug("Current events: " + secListenOnce.getCurrentEvents().length + " [" + Stream.of(secListenOnce.getCurrentEvents()).map(Class::getSimpleName).reduce((a, b) -> a + ", " + b) + "]");
boolean succeed = eventValue.init();
getParser().setCurrentEvents(oldEvents);

return succeed;
}

@Override
protected Object @NotNull [] get(@NotNull Event event) {
assert secListenOnce.getOuterEvent() != null;
var evtExpr = (EventValueExpression<?>) getExpr();
try {
var field = evtExpr.getClass().getDeclaredField("getters");
field.setAccessible(true);
var getters = (Map<Class<? extends Event>, Getter>) field.get(evtExpr);
getters.forEach((k, v) -> {
DiSky.debug("Getter: " + k.getSimpleName() + " / " + v);
});
DiSky.debug("given event class: " + secListenOnce.getOuterEvent().getClass().getSimpleName() + " / " + event.getClass().getSimpleName());
} catch (Exception e) {
e.printStackTrace();
}

return getExpr().getArray(secListenOnce.getOuterEvent());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ch.njol.skript.config.SectionNode;
import ch.njol.skript.lang.*;
import ch.njol.skript.util.Timespan;
import ch.njol.skript.variables.Variables;
import ch.njol.util.Kleenean;
import info.itsthesky.disky.DiSky;
import info.itsthesky.disky.api.events.DiSkyEvent;
Expand All @@ -17,9 +18,12 @@
import org.jetbrains.annotations.Nullable;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletionException;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;

import static info.itsthesky.disky.core.SkriptUtils.async;

Expand All @@ -41,6 +45,8 @@ public class SecListenOnce extends Section {

private Trigger trigger;
private @Nullable Trigger timeoutTrigger;
private @Nullable Event originalEvent;
private @Nullable Class<? extends Event>[] currentEvents;

@Override
public boolean init(Expression<?>[] expressions, int i, @NotNull Kleenean kleenean, SkriptParser.@NotNull ParseResult parseResult, @NotNull SectionNode sectionNode, @NotNull List<TriggerItem> list) {
Expand All @@ -49,6 +55,7 @@ public boolean init(Expression<?>[] expressions, int i, @NotNull Kleenean kleene
Skript.error("The event name in a listen once section must be a literal string!");
return false;
}
currentEvents = getParser().getCurrentEvents();

final String rawEvent = ((VariableString) expressions[0]).toString().replace("\"", "");
final Object result = SkriptParser.parseStatic(rawEvent, Skript.getEvents().iterator(), ParseContext.EVENT, "Cannot parse the given event: " + rawEvent);
Expand All @@ -71,6 +78,7 @@ public boolean init(Expression<?>[] expressions, int i, @NotNull Kleenean kleene
boolean deep;
if (exprTimeout == null) {
deep = false;
getParser().getCurrentSections().add(this);
final List<TriggerItem> items = SkriptUtils.loadCode(sectionNode);
trigger = new Trigger(getParser().getCurrentScript(), eventClass.getSimpleName(),
skriptEvent, items);
Expand All @@ -88,7 +96,19 @@ public boolean init(Expression<?>[] expressions, int i, @NotNull Kleenean kleene
return false;
}

// now we parse
// prepare stuff
getParser().getCurrentSections().add(this);

// We can't allow event-related expressions or effects inside
// the section. Although the given element will parse correctly,
// the given event upon execution will be the subscribe event, and
// not the 'outer' event.
/*var events = new ArrayList<>(Arrays.asList(currentEvents));
events.add((Class<? extends Event>) eventClass);
getParser().setCurrentEvents(events.toArray(new Class[0]));*/
getParser().setCurrentEvent("subscribe event", simpleEventClass);

// parse the code
final List<TriggerItem> items = SkriptUtils.loadCode((SectionNode) subNode);
trigger = new Trigger(getParser().getCurrentScript(), eventClass.getSimpleName(),
skriptEvent, items);
Expand All @@ -108,6 +128,7 @@ public boolean init(Expression<?>[] expressions, int i, @NotNull Kleenean kleene
@Nullable
protected TriggerItem walk(@NotNull Event event) {
Timespan timeout = exprTimeout == null ? null : exprTimeout.getSingle(event);
originalEvent = event;

final Bot bot = Bot.fromContext(exprBot, event);
async(() -> {
Expand All @@ -130,8 +151,10 @@ protected TriggerItem walk(@NotNull Event event) {
final SimpleDiSkyEvent simpleDiSkyEvent = simpleEventClass.getConstructor(newDiSkyEvent.getClass()).newInstance(newDiSkyEvent);
simpleDiSkyEvent.setJDAEvent((net.dv8tion.jda.api.events.Event) e);

Variables.setLocalVariables(simpleDiSkyEvent, Variables.copyLocalVariables(event));
trigger.execute(simpleDiSkyEvent);
} catch (Exception ex) {
System.out.println("Error while executing the event: ");
throw new RuntimeException(ex);
}

Expand All @@ -152,4 +175,22 @@ protected TriggerItem walk(@NotNull Event event) {
public @NotNull String toString(@Nullable Event event, boolean b) {
return "listen once to " + eventClass.getSimpleName() + " with timeout " + exprTimeout.toString(event, b);
}

public Event getOuterEvent() {
return originalEvent;
}

public @Nullable Class<? extends Event>[] getCurrentEvents() {
return currentEvents;
}

public <T> T executeInOuter(@NotNull Supplier<T> supplier) {
var oldEvents = getParser().getCurrentEvents();
getParser().setCurrentEvents(currentEvents);

final T result = supplier.get();

getParser().setCurrentEvents(oldEvents);
return result;
}
}

0 comments on commit 9cc3bf3

Please sign in to comment.