Implement server requests (#8)

* Implement server request API

* Add local server request

* Finish up server requests
This commit is contained in:
Austin Mayes 2019-01-19 21:34:37 -06:00 committed by ShinyDialga
parent ae0ea7e30a
commit aa46ee6dbc
9 changed files with 117 additions and 9 deletions

View File

@ -13,6 +13,8 @@ import tc.oc.api.message.types.PlayGameRequest;
import tc.oc.api.message.types.PlayerTeleportRequest;
import tc.oc.api.message.types.Reply;
import tc.oc.api.message.types.UpdateMultiResponse;
import tc.oc.api.message.types.UseServerRequest;
import tc.oc.api.message.types.UseServerResponse;
import tc.oc.api.servers.ServerSearchRequest;
import tc.oc.api.sessions.BadNickname;
import tc.oc.api.sessions.SessionChange;
@ -47,5 +49,8 @@ public class MessagesManifest extends HybridManifest {
messages.register(PlayGameRequest.class);
messages.register(CycleRequest.class);
messages.register(CycleResponse.class);
messages.register(UseServerRequest.class);
messages.register(UseServerResponse.class);
}
}

View File

@ -0,0 +1,13 @@
package tc.oc.api.message.types;
import javax.annotation.Nonnull;
import tc.oc.api.annotations.Serialize;
import tc.oc.api.message.Message;
import tc.oc.api.queue.MessageDefaults;
@Serialize
@MessageDefaults.RoutingKey("use_server")
@MessageDefaults.ExpirationMillis(10000)
public interface UseServerRequest extends Message {
@Nonnull String user_id();
}

View File

@ -0,0 +1,28 @@
package tc.oc.api.message.types;
import javax.annotation.Nullable;
import tc.oc.api.annotations.Serialize;
@Serialize
public interface UseServerResponse extends Reply {
String server_name();
boolean now();
UseServerResponse EMPTY = new UseServerResponse() {
@Override public String server_name() {
return "default";
}
@Override public boolean success() {
return true;
}
@Nullable @Override public String error() {
return null;
}
@Override public boolean now() {
return false;
}
};
}

View File

@ -4,6 +4,8 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import tc.oc.api.docs.Server;
import tc.oc.api.docs.virtual.ServerDoc;
import tc.oc.api.message.types.UseServerRequest;
import tc.oc.api.message.types.UseServerResponse;
import tc.oc.api.model.NullModelService;
public class NullServerService extends NullModelService<Server, ServerDoc.Partial> implements ServerService {
@ -12,4 +14,8 @@ public class NullServerService extends NullModelService<Server, ServerDoc.Partia
public ListenableFuture<?> doBungeeMetric(BungeeMetricRequest request) {
return Futures.immediateFuture(null);
}
@Override public ListenableFuture<UseServerResponse> requestServer(UseServerRequest request) {
return Futures.immediateFuture(UseServerResponse.EMPTY);
}
}

View File

@ -3,9 +3,13 @@ package tc.oc.api.servers;
import com.google.common.util.concurrent.ListenableFuture;
import tc.oc.api.docs.Server;
import tc.oc.api.docs.virtual.ServerDoc;
import tc.oc.api.message.types.UseServerRequest;
import tc.oc.api.message.types.UseServerResponse;
import tc.oc.api.model.ModelService;
public interface ServerService extends ModelService<Server, ServerDoc.Partial> {
ListenableFuture<?> doBungeeMetric(BungeeMetricRequest request);
ListenableFuture<UseServerResponse> requestServer(UseServerRequest request);
}

View File

@ -9,12 +9,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import tc.oc.api.docs.Server;
import tc.oc.api.docs.virtual.ServerDoc;
import tc.oc.api.message.types.FindMultiRequest;
import tc.oc.api.message.types.FindMultiResponse;
import tc.oc.api.message.types.FindRequest;
import tc.oc.api.message.types.PartialModelUpdate;
import tc.oc.api.message.types.UpdateMultiRequest;
import tc.oc.api.message.types.UpdateMultiResponse;
import tc.oc.api.message.types.*;
import tc.oc.api.model.NullModelService;
import tc.oc.api.servers.BungeeMetricRequest;
import tc.oc.api.servers.ServerService;
@ -54,4 +49,8 @@ public class LocalServerService extends NullModelService<Server, ServerDoc.Parti
request.documents().forEach(this::update);
return super.updateMulti(request);
}
@Override public ListenableFuture<UseServerResponse> requestServer(UseServerRequest request) {
return Futures.immediateFuture(UseServerResponse.EMPTY);
}
}

View File

@ -10,8 +10,12 @@ import tc.oc.api.docs.virtual.ServerDoc;
import tc.oc.api.http.HttpOption;
import tc.oc.api.message.types.FindMultiResponse;
import tc.oc.api.message.types.FindRequest;
import tc.oc.api.message.types.UseServerRequest;
import tc.oc.api.message.types.UseServerResponse;
import tc.oc.api.model.HttpModelService;
import tc.oc.api.queue.QueueQueryService;
import tc.oc.api.queue.Transaction;
import tc.oc.api.queue.Transaction.Factory;
import tc.oc.api.servers.BungeeMetricRequest;
import tc.oc.api.servers.ServerService;
@ -19,9 +23,11 @@ import tc.oc.api.servers.ServerService;
class OCNServerService extends HttpModelService<Server, ServerDoc.Partial> implements ServerService {
private final QueueQueryService<Server> queryService;
private final Transaction.Factory transactionFactory;
@Inject OCNServerService(QueueQueryService<Server> queryService) {
@Inject public OCNServerService(QueueQueryService<Server> queryService, Factory transactionFactory) {
this.queryService = queryService;
this.transactionFactory = transactionFactory;
}
@Override
@ -29,6 +35,10 @@ class OCNServerService extends HttpModelService<Server, ServerDoc.Partial> imple
return this.client().post("/servers/metric", request, HttpOption.INFINITE_RETRY);
}
@Override public ListenableFuture<UseServerResponse> requestServer(UseServerRequest request) {
return transactionFactory.request(request, UseServerResponse.class);
}
@Override
public ListenableFuture<FindMultiResponse<Server>> all() {
return queryService.all();

View File

@ -1,6 +1,7 @@
package tc.oc.commons.bungee.commands;
import java.util.concurrent.ExecutorService;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import com.google.common.util.concurrent.Futures;
@ -16,12 +17,19 @@ import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.CommandBypassException;
import tc.oc.api.bungee.users.BungeeUserStore;
import tc.oc.api.docs.Server;
import tc.oc.api.docs.virtual.ServerDoc;
import tc.oc.api.message.types.UseServerRequest;
import tc.oc.api.message.types.UseServerResponse;
import tc.oc.api.minecraft.users.UserStore;
import tc.oc.api.model.ModelSync;
import tc.oc.api.servers.ServerService;
import tc.oc.commons.bungee.servers.ServerTracker;
import tc.oc.commons.core.commands.Commands;
import tc.oc.commons.core.concurrent.Flexecutor;
import tc.oc.commons.core.restart.RestartManager;
import tc.oc.minecraft.scheduler.Sync;
public class ServerCommands implements Commands {
@ -29,12 +37,20 @@ public class ServerCommands implements Commands {
private final ServerTracker serverTracker;
private final ProxyServer proxy;
private final ExecutorService executor;
private final ServerService serverService;
private final BungeeUserStore userStore;
private final Flexecutor commandExecutor;
@Inject ServerCommands(RestartManager restartManager, ServerTracker serverTracker, ProxyServer proxy, @ModelSync ExecutorService executor) {
@Inject ServerCommands(RestartManager restartManager, ServerTracker serverTracker, ProxyServer proxy,
@ModelSync ExecutorService executor, ServerService serverService,
BungeeUserStore userStore, @Sync Flexecutor commandExecutor) {
this.restartManager = restartManager;
this.serverTracker = serverTracker;
this.proxy = proxy;
this.executor = executor;
this.serverService = serverService;
this.userStore = userStore;
this.commandExecutor = commandExecutor;
}
@Command(
@ -57,6 +73,33 @@ public class ServerCommands implements Commands {
}
}
@Command(
aliases = {"requestserver", "re"},
desc = "Request a server for yourself"
)
@CommandPermissions("ocn.requestserver")
public void request(final CommandContext args, CommandSender sender) throws CommandException {
if(sender instanceof ProxiedPlayer) {
final ProxiedPlayer player = (ProxiedPlayer) sender;
commandExecutor.callback(
serverService.requestServer(new UseServerRequest() {
@Nonnull @Override public String user_id() {
return userStore.getUser(player)._id();
}
}), (response) -> {
if (response.now()) {
player.connect(proxy.getServerInfo(response.server_name()));
player.sendMessage(new ComponentBuilder("Your server is already online! Connecting...").color(ChatColor.GREEN).create());
} else {
player.sendMessage(new ComponentBuilder("Server requested! Please wait up to two minutes before trying to connect to /server " +
response.server_name()).color(ChatColor.GOLD).create());
}
});
} else {
sender.sendMessage(new ComponentBuilder("Only players may use this command").color(ChatColor.RED).create());
}
}
@Command(
aliases = {"gserver"},
desc = "Global server teleport",

View File

@ -27,7 +27,7 @@ public abstract class AbstractRotationProvider implements RotationProvider {
Preconditions.checkNotNull(name, "rotation name");
synchronized(this) {
RotationState state = this.rotations.get(name);
if (state != null) return state
if (state != null) return state;
for (String key : this.rotations.keySet()) {
if (key.equalsIgnoreCase(name)) {