Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api-jvm-impl/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

dependencies {
api project(':api-jvm')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* ch.vorburger.minecraft.storeys
*
* Copyright (C) 2016 - 2018 Michael Vorburger.ch <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.japi.impl;

import ch.vorburger.minecraft.storeys.japi.Callback;
import ch.vorburger.minecraft.storeys.japi.Events;
import ch.vorburger.minecraft.storeys.japi.Script;
import ch.vorburger.minecraft.storeys.japi.util.CommandExceptions;
import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandMapping;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.spec.CommandSpec;

/**
* {@link Events} implementation.
* Created via {@link Scripts}.
*
* <p>The "lifecycle" of this is NOT a Singleton,
* but one for each new (possibly reloaded) {@link Script} instance.
*/
class EventsImpl implements Events, Unregisterable {

private static final Logger LOG = LoggerFactory.getLogger(EventsImpl.class);

private final Object plugin;
private final Collection<Unregisterable> unregistrables = new ConcurrentLinkedQueue<>();

EventsImpl(Object plugin) {
this.plugin = plugin;
}

@Override public void whenCommand(String name, Callback callback) {
CommandSpec spec = CommandSpec.builder().executor((src, args) -> {
CommandExceptions.doOrThrow("/" + name, () -> callback.invoke(new MinecraftJvmImpl(src)));
return CommandResult.success();
}).build();
Optional<CommandMapping> opt = Sponge.getCommandManager().register(plugin, spec, name);
if (!opt.isPresent()) {
LOG.error("Could not register new command, because it's already present: /" + name);
return;
}
unregistrables.add(() -> Sponge.getCommandManager().removeMapping(opt.get()));
}

@Override public void unregister() {
for (Unregisterable unregisterable : unregistrables) {
unregisterable.unregister();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* ch.vorburger.minecraft.storeys
*
* Copyright (C) 2016 - 2018 Michael Vorburger.ch <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.japi.impl;

import static java.util.Objects.requireNonNull;

import ch.vorburger.minecraft.storeys.japi.Events;
import ch.vorburger.minecraft.storeys.japi.Minecraft;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;

/**
* {@link Minecraft} implementation.
* Created indirectly (by EventsImpl) via {@link Scripts}.
*
* <p>The "lifecycle" of this is NOT a Singleton,
* but one for each instance (not just kind of) of an event registered on {@link Events},
* such as custom command, when right clicked, when player joined, when inside, etc.
*/
class MinecraftJvmImpl implements Minecraft {

private final CommandSource source;

MinecraftJvmImpl(CommandSource source) {
this.source = source;
}

@Override public void cmd(String command) {
String commandWithoutSlash = requireNonNull(command, "command").trim();
if (commandWithoutSlash.startsWith("/")) {
commandWithoutSlash = commandWithoutSlash.substring(1);
}
Sponge.getCommandManager().process(source, requireNonNull(commandWithoutSlash, "commandWithoutSlash"));
}

@Override public Player player() {
// TODO if (source instanceof Player), else... error handling TBD (not just log, but explain it to source)
return (Player) source;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* ch.vorburger.minecraft.storeys
*
* Copyright (C) 2016 - 2018 Michael Vorburger.ch <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.japi.impl;

import ch.vorburger.minecraft.storeys.japi.Script;
import com.google.errorprone.annotations.CheckReturnValue;

public final class Scripts {

// TODO Make Scripts @Inject-able...

@CheckReturnValue public static Unregisterable init(Object plugin, Script script) {
EventsImpl e = new EventsImpl(plugin);
script.init(e);
return e;
}

private Scripts() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.events;
package ch.vorburger.minecraft.storeys.japi.impl;

public interface Unregisterable {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* ch.vorburger.minecraft.storeys
*
* Copyright (C) 2016 - 2018 Michael Vorburger.ch <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.japi.util;

import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongepowered.api.command.CommandException;

/**
* Utilities for {@link CommandException}.
*
* @author Michael Vorburger.ch
*/
public final class CommandExceptions {

// Copy/pasted from https://github.com/vorburger/ch.vorburger.minecraft.osgi/blob/master/ch.vorburger.minecraft.osgi.api/src/main/java/ch/vorburger/minecraft/utils/CommandExceptions.java

private static final Logger LOG = LoggerFactory.getLogger(CommandExceptions.class);

private CommandExceptions() {
}

/**
* Invoke 'callable' and return its value,
* or rethrow any Exception from it wrapped in a CommandException,
* with description.
*
* @param description a humand-readable description of the Callable (used in the CommandException)
* @param callable the code to invoke
* @return the value returned by the callable
* @throws CommandException in case the callable failed with an Exception
*/
public static <T> T getOrThrow(String description, Callable<T> callable) throws CommandException {
try {
return callable.call();
} catch (Exception cause) {
// TODO see isDeveloper() idea in Texts.fromThrowable
throw new CommandException(Texts.fromThrowable(description, cause), cause, true);
}
}

public static void doOrThrow(String description, RunnableWithException runnable) throws CommandException {
try {
runnable.run();
} catch (Exception cause) {
// TODO once the cause is properly throw to the user incl. stack trace, this log is probably redundant; then remove?
LOG.error("doOrThrow()", cause);
// TODO see isDeveloper() idea in Texts.fromThrowable
throw new CommandException(Texts.fromThrowable(description, cause), cause, true);
}
}

public static CommandException create(String message) {
return new CommandException(Texts.inRed(message));
}

@FunctionalInterface
public interface RunnableWithException {
void run() throws Exception;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* ch.vorburger.minecraft.storeys
*
* Copyright (C) 2016 - 2018 Michael Vorburger.ch <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.japi.util;

import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.format.TextColors;

/**
* Utilities for {@link Text}.
*
* @author Michael Vorburger.ch
*/
public final class Texts {

// Copy/pasted from https://github.com/vorburger/ch.vorburger.minecraft.osgi/blob/master/ch.vorburger.minecraft.osgi.api/src/main/java/ch/vorburger/minecraft/utils/Texts.java

private Texts() {
}

public static Text fromThrowable(String prefix, Throwable throwable) {
// TODO have a Player isDeveloper flag (or Permission, probably..)
// developers get to see the cause stack trace? ;) Noob do not.
return Text.builder().color(TextColors.RED).append(Text.of(prefix + throwable.getMessage())).build();
// TODO add StackTrace here - with links being able to click on to jump into sources!!!
}

public static Text inRed(String content) {
return Text.builder().color(TextColors.RED).append(Text.of(content)).build();
}
}
5 changes: 5 additions & 0 deletions api-jvm/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

// TODO Build refactoring so that this module inherits only spongeapi WITHOUT everything else from the subprojects {} in ../build.gradle

dependencies {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* ch.vorburger.minecraft.storeys
*
* Copyright (C) 2016 - 2018 Michael Vorburger.ch <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.japi;

@FunctionalInterface
public interface Callback {

void invoke(Minecraft m) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* ch.vorburger.minecraft.storeys
*
* Copyright (C) 2016 - 2018 Michael Vorburger.ch <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.vorburger.minecraft.storeys.japi;

public interface Events {

// This is intentionally NOT returning CommandResult, to keep it simple, for scripting.
void whenCommand(String name, Callback callback);

// TODO add more "event handlers" here; see
// https://github.com/OASIS-learn-study/minecraft-storeys-maker/blob/develop/api/src/main/typescript/observable-wrapper.ts
}
Loading