-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Report and ban update (saving urls into world save data)
- Loading branch information
Showing
22 changed files
with
1,358 additions
and
488 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.teacon.slides.admin; | ||
|
||
import com.mojang.brigadier.Command; | ||
import com.mojang.brigadier.builder.LiteralArgumentBuilder; | ||
import com.mojang.brigadier.context.CommandContext; | ||
import com.mojang.brigadier.exceptions.CommandSyntaxException; | ||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; | ||
import net.minecraft.FieldsAreNonnullByDefault; | ||
import net.minecraft.MethodsReturnNonnullByDefault; | ||
import net.minecraft.commands.CommandSourceStack; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraftforge.event.RegisterCommandsEvent; | ||
import net.minecraftforge.eventbus.api.SubscribeEvent; | ||
import net.minecraftforge.fml.common.Mod; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.teacon.slides.SlideShow; | ||
import org.teacon.slides.url.ProjectorURLArgument; | ||
import org.teacon.slides.url.ProjectorURLSavedData; | ||
|
||
import javax.annotation.ParametersAreNonnullByDefault; | ||
import java.util.Optional; | ||
import java.util.UUID; | ||
|
||
import static net.minecraft.commands.Commands.argument; | ||
import static net.minecraft.commands.Commands.literal; | ||
|
||
@FieldsAreNonnullByDefault | ||
@MethodsReturnNonnullByDefault | ||
@ParametersAreNonnullByDefault | ||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) | ||
public class SlideCommand { | ||
private static final DynamicCommandExceptionType URL_NOT_EXIST = new DynamicCommandExceptionType(v -> Component.translatable("command.slide_show.failed.url_not_exist", v)); | ||
|
||
@SubscribeEvent | ||
public static void onCommandsRegister(RegisterCommandsEvent event) { | ||
var node = event.getDispatcher().register(command(SlideShow.ID.replace('_', '-'))); | ||
event.getDispatcher().register(literal(StringUtils.substringBefore(SlideShow.ID, '_')).redirect(node)); | ||
} | ||
|
||
private static LiteralArgumentBuilder<CommandSourceStack> command(String name) { | ||
return literal(name) | ||
.then(literal("block") | ||
.then(argument("url", new ProjectorURLArgument()) | ||
.executes(SlideCommand::blockByProjectorUrl))) | ||
.then(literal("unblock") | ||
.then(argument("url", new ProjectorURLArgument()) | ||
.executes(SlideCommand::unblockByProjectorUrl))); | ||
} | ||
|
||
private static int blockByProjectorUrl(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException { | ||
// noinspection DuplicatedCode | ||
var level = ctx.getSource().getLevel(); | ||
var data = ProjectorURLSavedData.get(level); | ||
var arg = ProjectorURLArgument.getUrl(ctx, "url"); | ||
var urlOptional = arg.map(data::getUrlById, Optional::of); | ||
var uuidOptional = arg.map(Optional::of, data::getIdByUrl); | ||
if (urlOptional.isPresent() && uuidOptional.isPresent()) { | ||
var url = urlOptional.get(); | ||
var uuid = uuidOptional.get(); | ||
if (data.setBlockedStatusByCommand(uuid, url, ctx.getSource(), true)) { | ||
var msg = Component.translatable("command.slide_show.block_projector_url.success", url, uuid); | ||
ctx.getSource().sendSuccess(msg, true); | ||
return Command.SINGLE_SUCCESS; | ||
} | ||
} | ||
throw URL_NOT_EXIST.create(arg.map(UUID::toString, u -> u.toUrl().toString())); | ||
} | ||
|
||
private static int unblockByProjectorUrl(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException { | ||
// noinspection DuplicatedCode | ||
var level = ctx.getSource().getLevel(); | ||
var data = ProjectorURLSavedData.get(level); | ||
var arg = ProjectorURLArgument.getUrl(ctx, "url"); | ||
var urlOptional = arg.map(data::getUrlById, Optional::of); | ||
var uuidOptional = arg.map(Optional::of, data::getIdByUrl); | ||
if (urlOptional.isPresent() && uuidOptional.isPresent()) { | ||
var url = urlOptional.get(); | ||
var uuid = uuidOptional.get(); | ||
if (data.setBlockedStatusByCommand(uuid, url, ctx.getSource(), false)) { | ||
var msg = Component.translatable("command.slide_show.unblock_projector_url.success", url, uuid); | ||
ctx.getSource().sendSuccess(msg, true); | ||
return Command.SINGLE_SUCCESS; | ||
} | ||
} | ||
throw URL_NOT_EXIST.create(arg.map(UUID::toString, u -> u.toUrl().toString())); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...on/slides/permission/SlidePermission.java → .../teacon/slides/admin/SlidePermission.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
src/main/java/org/teacon/slides/network/ProjectorURLPrefetchPacket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package org.teacon.slides.network; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import com.google.common.collect.ImmutableSet; | ||
import net.minecraft.FieldsAreNonnullByDefault; | ||
import net.minecraft.MethodsReturnNonnullByDefault; | ||
import net.minecraft.network.FriendlyByteBuf; | ||
import net.minecraft.server.level.ServerPlayer; | ||
import net.minecraftforge.network.NetworkEvent; | ||
import net.minecraftforge.network.PacketDistributor; | ||
import org.teacon.slides.ModRegistries; | ||
import org.teacon.slides.renderer.SlideState; | ||
import org.teacon.slides.url.ProjectorURL; | ||
import org.teacon.slides.url.ProjectorURLSavedData; | ||
|
||
import javax.annotation.ParametersAreNonnullByDefault; | ||
import java.util.Set; | ||
import java.util.UUID; | ||
import java.util.function.Supplier; | ||
|
||
@FieldsAreNonnullByDefault | ||
@MethodsReturnNonnullByDefault | ||
@ParametersAreNonnullByDefault | ||
public final class ProjectorURLPrefetchPacket { | ||
private final ImmutableSet<UUID> blockedIdSet; | ||
|
||
private final ImmutableSet<UUID> nonExistentIdSet; | ||
|
||
private final ImmutableMap<UUID, ProjectorURL> unblockedIdMap; | ||
|
||
private enum Status { | ||
END, BLOCKED, NON_EXISTENT, UNBLOCKED | ||
} | ||
|
||
public ProjectorURLPrefetchPacket(Set<UUID> idSet, ProjectorURLSavedData data) { | ||
var blockedIdSetBuilder = ImmutableSet.<UUID>builder(); | ||
var nonExistentIdSetBuilder = ImmutableSet.<UUID>builder(); | ||
var unblockedIdMapBuilder = ImmutableMap.<UUID, ProjectorURL>builder(); | ||
for (var id : idSet) { | ||
var url = data.getUrlById(id); | ||
var isBlocked = data.isUrlBlocked(id); | ||
if (isBlocked) { | ||
blockedIdSetBuilder.add(id); | ||
} else if (url.isEmpty()) { | ||
nonExistentIdSetBuilder.add(id); | ||
} else { | ||
unblockedIdMapBuilder.put(id, url.get()); | ||
} | ||
} | ||
this.blockedIdSet = blockedIdSetBuilder.build(); | ||
this.nonExistentIdSet = nonExistentIdSetBuilder.build(); | ||
this.unblockedIdMap = unblockedIdMapBuilder.build(); | ||
} | ||
|
||
public ProjectorURLPrefetchPacket(FriendlyByteBuf buf) { | ||
var blockedIdSetBuilder = ImmutableSet.<UUID>builder(); | ||
var nonExistentIdSetBuilder = ImmutableSet.<UUID>builder(); | ||
var unblockedIdMapBuilder = ImmutableMap.<UUID, ProjectorURL>builder(); | ||
while (true) { | ||
switch (buf.readEnum(Status.class)) { | ||
case END -> { | ||
this.blockedIdSet = blockedIdSetBuilder.build(); | ||
this.nonExistentIdSet = nonExistentIdSetBuilder.build(); | ||
this.unblockedIdMap = unblockedIdMapBuilder.build(); | ||
return; | ||
} | ||
case BLOCKED -> blockedIdSetBuilder.add(buf.readUUID()); | ||
case NON_EXISTENT -> nonExistentIdSetBuilder.add(buf.readUUID()); | ||
case UNBLOCKED -> unblockedIdMapBuilder.put(buf.readUUID(), new ProjectorURL(buf.readUtf())); | ||
} | ||
} | ||
} | ||
|
||
public void write(FriendlyByteBuf buf) { | ||
this.blockedIdSet.forEach(uuid -> buf.writeEnum(Status.BLOCKED).writeUUID(uuid)); | ||
this.nonExistentIdSet.forEach(uuid -> buf.writeEnum(Status.NON_EXISTENT).writeUUID(uuid)); | ||
this.unblockedIdMap.forEach((uuid, url) -> buf.writeEnum(Status.UNBLOCKED).writeUUID(uuid).writeUtf(url.toUrl().toString())); | ||
buf.writeEnum(Status.END); | ||
} | ||
|
||
public void sendToAll() { | ||
ModRegistries.CHANNEL.send(PacketDistributor.ALL.noArg(), this); | ||
} | ||
|
||
public void sendToClient(ServerPlayer player) { | ||
ModRegistries.CHANNEL.send(PacketDistributor.PLAYER.with(() -> player), this); | ||
} | ||
|
||
public void handle(Supplier<NetworkEvent.Context> context) { | ||
context.get().enqueueWork(() -> SlideState.applyPrefetch(this.blockedIdSet, this.nonExistentIdSet, this.unblockedIdMap)); | ||
context.get().setPacketHandled(true); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
src/main/java/org/teacon/slides/network/ProjectorURLRequestPacket.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.teacon.slides.network; | ||
|
||
import com.google.common.collect.ImmutableSet; | ||
import net.minecraft.FieldsAreNonnullByDefault; | ||
import net.minecraft.MethodsReturnNonnullByDefault; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.network.FriendlyByteBuf; | ||
import net.minecraftforge.network.NetworkEvent; | ||
import org.teacon.slides.ModRegistries; | ||
import org.teacon.slides.projector.ProjectorBlockEntity; | ||
import org.teacon.slides.url.ProjectorURLSavedData; | ||
|
||
import javax.annotation.ParametersAreNonnullByDefault; | ||
import java.util.LinkedHashSet; | ||
import java.util.UUID; | ||
import java.util.function.Supplier; | ||
|
||
@FieldsAreNonnullByDefault | ||
@MethodsReturnNonnullByDefault | ||
@ParametersAreNonnullByDefault | ||
public final class ProjectorURLRequestPacket { | ||
private final ImmutableSet<BlockPos> requestedPosSet; | ||
|
||
public ProjectorURLRequestPacket(Iterable<BlockPos> requested) { | ||
this.requestedPosSet = ImmutableSet.copyOf(requested); | ||
} | ||
|
||
public ProjectorURLRequestPacket(FriendlyByteBuf buf) { | ||
var builder = ImmutableSet.<BlockPos>builder(); | ||
for (var hasNext = buf.readBoolean(); hasNext; hasNext = buf.readBoolean()) { | ||
builder.add(new BlockPos(buf.readVarInt(), buf.readVarInt(), buf.readVarInt())); | ||
} | ||
this.requestedPosSet = builder.build(); | ||
} | ||
|
||
public void write(FriendlyByteBuf buf) { | ||
for (var pos : this.requestedPosSet) { | ||
buf.writeBoolean(true); | ||
buf.writeVarInt(pos.getX()); | ||
buf.writeVarInt(pos.getY()); | ||
buf.writeVarInt(pos.getZ()); | ||
} | ||
buf.writeBoolean(false); | ||
} | ||
|
||
public void sendToServer() { | ||
ModRegistries.CHANNEL.sendToServer(this); | ||
} | ||
|
||
public void handle(Supplier<NetworkEvent.Context> context) { | ||
context.get().enqueueWork(() -> { | ||
var player = context.get().getSender(); | ||
if (player != null) { | ||
var level = player.getLevel(); | ||
var imageLocations = new LinkedHashSet<UUID>(this.requestedPosSet.size()); | ||
for (var pos : this.requestedPosSet) { | ||
// prevent remote chunk loading | ||
if (level.isLoaded(pos) && level.getBlockEntity(pos) instanceof ProjectorBlockEntity tile) { | ||
imageLocations.add(tile.getImageLocation()); | ||
} | ||
} | ||
var data = ProjectorURLSavedData.get(level); | ||
new ProjectorURLPrefetchPacket(imageLocations, data).sendToClient(player); | ||
} | ||
}); | ||
context.get().setPacketHandled(true); | ||
} | ||
} |
Oops, something went wrong.