From a7b23460650c621c0ce8d6125e1bde954e6fb9b5 Mon Sep 17 00:00:00 2001 From: Kamesuta Date: Wed, 28 Sep 2016 22:50:42 +0900 Subject: [PATCH] Prevent Anti-AutoSign & Config --- .../java/com/kamesuta/mc/signpic/Client.java | 2 - .../java/com/kamesuta/mc/signpic/Config.java | 120 +++++++++++++++++- .../com/kamesuta/mc/signpic/Reference.java | 1 + .../com/kamesuta/mc/signpic/SignPicture.java | 4 +- .../mc/signpic/entry/EntryManager.java | 5 +- .../kamesuta/mc/signpic/entry/EntrySlot.java | 9 +- .../content/ContentCapacityOverException.java | 20 +++ .../entry/content/ContentDownloader.java | 6 + .../signpic/entry/content/ContentManager.java | 55 ++++---- .../mc/signpic/entry/content/ContentSlot.java | 9 +- .../gui/{GuiPacketWait.java => GuiPAAS.java} | 31 ++--- .../mc/signpic/gui/config/ConfigGui.java | 52 ++++++++ .../signpic/gui/config/ConfigGuiFactory.java | 35 +++++ .../mc/signpic/handler/CoreHandler.java | 8 ++ .../mc/signpic/handler/SignHandler.java | 4 +- .../mc/signpic/image/ImageIOLoader.java | 7 +- .../mc/signpic/image/RemoteImage.java | 4 + .../mc/signpic/image/meta/ImageSize.java | 5 +- .../information/InformationChecker.java | 38 +++--- .../mc/signpic/proxy/ClientProxy.java | 2 - .../render/CustomTileEntitySignRenderer.java | 3 +- .../mc/signpic/render/SignPicRender.java | 5 +- .../com/kamesuta/mc/signpic/util/Sign.java | 24 ++-- .../resources/assets/signpic/lang/en_US.lang | 11 +- .../resources/assets/signpic/lang/ja_JP.lang | 11 +- 25 files changed, 371 insertions(+), 100 deletions(-) create mode 100644 src/main/java/com/kamesuta/mc/signpic/entry/content/ContentCapacityOverException.java rename src/main/java/com/kamesuta/mc/signpic/gui/{GuiPacketWait.java => GuiPAAS.java} (72%) create mode 100644 src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGui.java create mode 100644 src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGuiFactory.java diff --git a/src/main/java/com/kamesuta/mc/signpic/Client.java b/src/main/java/com/kamesuta/mc/signpic/Client.java index c3404f1a..cf748f54 100644 --- a/src/main/java/com/kamesuta/mc/signpic/Client.java +++ b/src/main/java/com/kamesuta/mc/signpic/Client.java @@ -25,8 +25,6 @@ public class Client { public static File mcDir; public static File signpicDir; public static File signpicCacheDir; - public static File configDir; - public static File configFile; public static File modDir; public static File modFile; diff --git a/src/main/java/com/kamesuta/mc/signpic/Config.java b/src/main/java/com/kamesuta/mc/signpic/Config.java index 345c6a97..3dd6887b 100644 --- a/src/main/java/com/kamesuta/mc/signpic/Config.java +++ b/src/main/java/com/kamesuta/mc/signpic/Config.java @@ -1,7 +1,119 @@ package com.kamesuta.mc.signpic; -// TODO -public class Config { - public Config() { +import java.io.File; + +import org.apache.commons.lang3.StringUtils; + +import com.kamesuta.mc.signpic.handler.CoreEvent; + +import cpw.mods.fml.client.event.ConfigChangedEvent; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +public final class Config extends Configuration { + public static Config instance; + + private final File configFile; + public boolean updatable; + + public int imageWidthLimit = 512; + public int imageHeightLimit = 512; + public boolean imageAnimationGif = true; + + public int entryGCtick = 15; + + public int contentLoadThreads = 3; + public int contentMaxByte = 0; + public int contentGCtick = 15 * 20; + public int contentAsyncTick = 0; + public int contentSyncTick = 0; + + public boolean informationNotice = true; + public boolean informationJoinBeta = false; + + public boolean multiplayPAAS = true; + /** Fastest time "possible" estimate for an empty sign. */ + public int multiplayPAASMinEditTime = 150; + /** Minimum time needed to add one extra line (not the first). */ + public int multiplayPAASMinLineTime = 50; + /** Minimum time needed to type a character. */ + public int multiplayPAASMinCharTime = 50; + + public float renderSeeOpacity = .5f; + public float renderPreviewFixedOpacity = .7f; + public float renderPreviewFloatedOpacity = .7f; + + public Config( final File configFile ) { + super( configFile ); + this.configFile = configFile; + + this.imageWidthLimit = get( "Image", "WidthLimit", this.imageWidthLimit ).setRequiresMcRestart(true).getInt( this.imageWidthLimit ); + this.imageHeightLimit = get( "Image", "HeightLimit", this.imageHeightLimit ).setRequiresMcRestart(true).getInt( this.imageHeightLimit ); + this.imageAnimationGif = get( "Image", "AnimateGif", this.imageAnimationGif ).setRequiresMcRestart(true).getBoolean( this.imageAnimationGif ); + + addCustomCategoryComment("Entry", "Entry(sign text parse cache) Management"); + + addCustomCategoryComment("Content", "Content Data Management"); + + this.informationNotice = get( "Version", "Notice", this.informationNotice ).setRequiresMcRestart(true).getBoolean( this.informationNotice ); + this.informationJoinBeta = get( "Version", "JoinBeta", this.informationJoinBeta ).setRequiresMcRestart(true).getBoolean( this.informationJoinBeta ); + + addCustomCategoryComment("MultiplayPreventAntiAutoSign", "Prevent from Anti-AutoSign Plugin such as NoCheatPlus. (ms)"); + + changeableSync(); + + this.updatable = true; + } + + private void changeableSync() { + this.entryGCtick = get( "Entry", "GCDelayTick", this.entryGCtick ).getInt( this.entryGCtick ); + + this.contentLoadThreads = addComment(get( "Content", "LoadThreads", this.contentLoadThreads ), "parallel processing number such as Downloading").setRequiresMcRestart(true).getInt( this.contentLoadThreads ); + this.contentMaxByte = addComment(get( "Content", "MaxByte", this.contentMaxByte ), "limit of size before downloading").getInt( this.contentMaxByte ); + this.contentGCtick = addComment(get( "Content", "GCDelayTick", this.contentGCtick ), "delay ticks of Garbage Collection").getInt( this.contentGCtick ); + this.contentAsyncTick = addComment(get( "Content", "AsyncLoadDelayTick", this.contentAsyncTick ), "ticks of Async process starting delay (Is other threads, it does not disturb the operation) such as Downloading, File Loading...").getInt( this.contentAsyncTick ); + this.contentSyncTick = addComment(get( "Content", "SyncLoadIntervalTick", this.contentSyncTick ), "ticks of Sync process interval (A drawing thread, affects the behavior. Please increase the value if the operation is heavy.) such as Gl Texture Uploading").getInt( this.contentSyncTick ); + + this.multiplayPAAS = get( "MultiplayPreventAntiAutoSign", "Enable", this.multiplayPAAS ).getBoolean( this.multiplayPAAS ); + this.multiplayPAASMinEditTime = get( "MultiplayPreventAntiAutoSign", "minEditTime", this.multiplayPAASMinEditTime ).getInt( this.multiplayPAASMinEditTime ); + this.multiplayPAASMinLineTime = get( "MultiplayPreventAntiAutoSign", "minLineTime", this.multiplayPAASMinLineTime ).getInt( this.multiplayPAASMinLineTime ); + this.multiplayPAASMinCharTime = get( "MultiplayPreventAntiAutoSign", "minCharTime", this.multiplayPAASMinCharTime ).getInt( this.multiplayPAASMinCharTime ); + + this.renderSeeOpacity = (float) get( "Render", "ViewSignOpacity", this.renderSeeOpacity ).getDouble( this.renderSeeOpacity ); + this.renderPreviewFixedOpacity = (float) get( "Render", "PreviewFixedSignOpacity", this.renderPreviewFixedOpacity ).getDouble( this.renderPreviewFixedOpacity ); + this.renderPreviewFloatedOpacity = (float) get( "Render", "PreviewFloatedSignOpacity", this.renderPreviewFloatedOpacity ).getDouble( this.renderPreviewFloatedOpacity ); + } + + private Property addComment(final Property prop, final String comment) { + prop.comment = comment; + return prop; + } + + @Override + public void save() + { + if( hasChanged() ) + { + super.save(); + } + } + + @CoreEvent + public void onConfigChanged( final ConfigChangedEvent.OnConfigChangedEvent eventArgs ) + { + if( StringUtils.equals(eventArgs.modID, Reference.MODID) ) + { + changeableSync(); + + if( this.updatable ) + { + save(); + } + } + } + + public String getFilePath() + { + return this.configFile.getPath(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/kamesuta/mc/signpic/Reference.java b/src/main/java/com/kamesuta/mc/signpic/Reference.java index 0ed99e47..bbd7e342 100644 --- a/src/main/java/com/kamesuta/mc/signpic/Reference.java +++ b/src/main/java/com/kamesuta/mc/signpic/Reference.java @@ -11,6 +11,7 @@ public class Reference { public static final String MINECRAFT = "${mcversion}"; public static final String PROXY_SERVER = "com.kamesuta.mc.signpic.proxy.CommonProxy"; public static final String PROXY_CLIENT = "com.kamesuta.mc.signpic.proxy.ClientProxy"; + public static final String GUI_FACTORY = "com.kamesuta.mc.signpic.gui.config.ConfigGuiFactory"; public static Logger logger = LogManager.getLogger(Reference.MODID); } diff --git a/src/main/java/com/kamesuta/mc/signpic/SignPicture.java b/src/main/java/com/kamesuta/mc/signpic/SignPicture.java index 0e23e169..5575c355 100644 --- a/src/main/java/com/kamesuta/mc/signpic/SignPicture.java +++ b/src/main/java/com/kamesuta/mc/signpic/SignPicture.java @@ -14,7 +14,7 @@ import cpw.mods.fml.common.network.NetworkCheckHandler; import cpw.mods.fml.relauncher.Side; -@Mod(modid = Reference.MODID, name = Reference.NAME, version = Reference.VERSION) +@Mod(modid = Reference.MODID, name = Reference.NAME, version = Reference.VERSION, guiFactory = Reference.GUI_FACTORY) public class SignPicture { @Instance(Reference.MODID) public static SignPicture instance; @@ -29,6 +29,7 @@ public boolean checkModList(final Map versions, final Side side) @EventHandler public void preInit(final FMLPreInitializationEvent event) { + Config.instance = new Config(event.getSuggestedConfigurationFile()); proxy.preInit(event); } @@ -40,5 +41,6 @@ public void init(final FMLInitializationEvent event) { @EventHandler public void postInit(final FMLPostInitializationEvent event) { proxy.postInit(event); + Config.instance.save(); } } diff --git a/src/main/java/com/kamesuta/mc/signpic/entry/EntryManager.java b/src/main/java/com/kamesuta/mc/signpic/entry/EntryManager.java index f7f49e2d..3fb3a255 100644 --- a/src/main/java/com/kamesuta/mc/signpic/entry/EntryManager.java +++ b/src/main/java/com/kamesuta/mc/signpic/entry/EntryManager.java @@ -2,8 +2,6 @@ import java.util.Iterator; import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import com.google.common.collect.Maps; import com.kamesuta.mc.signpic.handler.CoreEvent; @@ -11,10 +9,9 @@ public class EntryManager implements ITickEntry { public static final EntryManager instance = new EntryManager(); - public final ExecutorService threadpool = Executors.newFixedThreadPool(3); private final Map> registry = Maps.newHashMap(); - public Entry get(final EntryId id) { + protected Entry get(final EntryId id) { final EntrySlot entries = this.registry.get(id); if (entries!=null) return entries.get(); diff --git a/src/main/java/com/kamesuta/mc/signpic/entry/EntrySlot.java b/src/main/java/com/kamesuta/mc/signpic/entry/EntrySlot.java index 545fdc61..be3e22af 100644 --- a/src/main/java/com/kamesuta/mc/signpic/entry/EntrySlot.java +++ b/src/main/java/com/kamesuta/mc/signpic/entry/EntrySlot.java @@ -1,7 +1,8 @@ package com.kamesuta.mc.signpic.entry; +import com.kamesuta.mc.signpic.Config; + public class EntrySlot { - public static final int CollectTimes = 20 * 15; protected static long times = 0; protected final T entry; @@ -23,10 +24,14 @@ public EntrySlot used() { } public boolean shouldCollect() { - return times - this.time > CollectTimes; + return times - this.time > getCollectTimes(); } public static void Tick() { times++; } + + protected int getCollectTimes() { + return Config.instance.entryGCtick; + } } diff --git a/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentCapacityOverException.java b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentCapacityOverException.java new file mode 100644 index 00000000..29e3be22 --- /dev/null +++ b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentCapacityOverException.java @@ -0,0 +1,20 @@ +package com.kamesuta.mc.signpic.entry.content; + +import java.io.IOException; + +public class ContentCapacityOverException extends IOException { + public ContentCapacityOverException() { + } + + public ContentCapacityOverException(final String message) { + super(message); + } + + public ContentCapacityOverException(final Throwable cause) { + super(cause); + } + + public ContentCapacityOverException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentDownloader.java b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentDownloader.java index fbf844f6..4284681b 100644 --- a/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentDownloader.java +++ b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentDownloader.java @@ -14,6 +14,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.IAsyncProcessable; import com.kamesuta.mc.signpic.util.Downloader; @@ -38,6 +39,11 @@ public void onAsyncProcess() throws URISyntaxException, IllegalStateException, I final HttpResponse response = Downloader.downloader.client.execute(req); final HttpEntity entity = response.getEntity(); + final long max = Config.instance.contentMaxByte; + final long size = entity.getContentLength(); + if (max > 0 && (size < 0 || size > max)) + throw new ContentCapacityOverException(); + this.content.state.progress.overall = entity.getContentLength(); input = entity.getContent(); countoutput = new CountingOutputStream(new BufferedOutputStream(new FileOutputStream(local))) { diff --git a/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentManager.java b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentManager.java index 15e73458..06f45c45 100644 --- a/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentManager.java +++ b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentManager.java @@ -8,6 +8,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.IAsyncProcessable; import com.kamesuta.mc.signpic.entry.IDivisionProcessable; import com.kamesuta.mc.signpic.entry.ITickEntry; @@ -16,15 +17,17 @@ public class ContentManager implements ITickEntry { public static ContentManager instance = new ContentManager(); - public final ExecutorService threadpool = Executors.newFixedThreadPool(3); + public final ExecutorService threadpool = Executors.newFixedThreadPool(Config.instance.contentLoadThreads); protected final HashMap> registry = new HashMap>(); public Deque asyncqueue = new ArrayDeque(); public Deque divisionqueue = new ArrayDeque(); + private int asynctick = 0; + private int divisiontick = 0; - public ContentManager() { + private ContentManager() { } - public Content get(final ContentId id) { + protected Content get(final ContentId id) { final ContentSlot entries = this.registry.get(id); if (entries!=null) return entries.get(); @@ -38,28 +41,36 @@ public Content get(final ContentId id) { @CoreEvent @Override public void onTick() { - IAsyncProcessable asyncprocess; - if ((asyncprocess = this.asyncqueue.poll()) != null) { - final IAsyncProcessable asyncprocessexec = asyncprocess; - this.threadpool.execute(new Runnable() { - @Override - public void run() { - try { - asyncprocessexec.onAsyncProcess(); - } catch (final Exception e) { - e.printStackTrace(); + this.asynctick++; + if (this.asynctick > Config.instance.contentAsyncTick) { + this.asynctick = 0; + IAsyncProcessable asyncprocess; + if ((asyncprocess = this.asyncqueue.poll()) != null) { + final IAsyncProcessable asyncprocessexec = asyncprocess; + this.threadpool.execute(new Runnable() { + @Override + public void run() { + try { + asyncprocessexec.onAsyncProcess(); + } catch (final Exception e) { + e.printStackTrace(); + } } - } - }); + }); + } } - IDivisionProcessable divisionprocess; - if ((divisionprocess = this.divisionqueue.peek()) != null) { - try { - if (divisionprocess.onDivisionProcess()) { - this.divisionqueue.poll(); + this.divisiontick++; + if (this.divisiontick > Config.instance.contentAsyncTick) { + this.divisiontick = 0; + IDivisionProcessable divisionprocess; + if ((divisionprocess = this.divisionqueue.peek()) != null) { + try { + if (divisionprocess.onDivisionProcess()) { + this.divisionqueue.poll(); + } + } catch (final Exception e) { + e.printStackTrace(); } - } catch (final Exception e) { - e.printStackTrace(); } } diff --git a/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentSlot.java b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentSlot.java index 17e64a74..edc45078 100644 --- a/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentSlot.java +++ b/src/main/java/com/kamesuta/mc/signpic/entry/content/ContentSlot.java @@ -1,13 +1,11 @@ package com.kamesuta.mc.signpic.entry.content; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.EntrySlot; import com.kamesuta.mc.signpic.entry.ICollectable; import com.kamesuta.mc.signpic.entry.IInitable; public class ContentSlot extends EntrySlot implements IInitable, ICollectable { - public static int CollectTimes = 20 * 15; - public static long times = 0; - private boolean init = true; public ContentSlot(final T entry) { @@ -28,4 +26,9 @@ public boolean shouldInit() { public void onCollect() { this.entry.onCollect(); } + + @Override + protected int getCollectTimes() { + return Config.instance.contentGCtick; + } } \ No newline at end of file diff --git a/src/main/java/com/kamesuta/mc/signpic/gui/GuiPacketWait.java b/src/main/java/com/kamesuta/mc/signpic/gui/GuiPAAS.java similarity index 72% rename from src/main/java/com/kamesuta/mc/signpic/gui/GuiPacketWait.java rename to src/main/java/com/kamesuta/mc/signpic/gui/GuiPAAS.java index 5dabea63..47046e91 100644 --- a/src/main/java/com/kamesuta/mc/signpic/gui/GuiPacketWait.java +++ b/src/main/java/com/kamesuta/mc/signpic/gui/GuiPAAS.java @@ -21,14 +21,15 @@ import com.kamesuta.mc.signpic.render.RenderHelper; import com.kamesuta.mc.signpic.util.Sign.SendPacketTask; +import net.minecraft.client.resources.I18n; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntitySign; -public class GuiPacketWait extends WFrame { +public class GuiPAAS extends WFrame { private final SendPacketTask task; private boolean preview; - public GuiPacketWait(final SendPacketTask task) { + public GuiPAAS(final SendPacketTask task) { this.task = task; } @@ -38,7 +39,7 @@ protected void init() { CurrentMode.instance.setState(CurrentMode.State.PREVIEW, false); add(new WPanel(RArea.diff(0, 0, 0, 0)) { - private final int max = StringUtils.length(GuiPacketWait.this.task.id.id()); + private final int max = StringUtils.length(GuiPAAS.this.task.id.id()); private int cursor; private boolean close = true; private int c; @@ -68,8 +69,8 @@ public void draw(final WEvent ev, final Area pgp, final Point p, final float fra glTranslatef(a.x1()+a.w()/2, a.y1(), 50f); glScalef(-f1, -f1, -f1); glRotatef(180f, 0f, 1f, 0f); - Client.renderer.translateBase(GuiPacketWait.this.task.entity, -0.5D, -0.75D, -0.5D, -1f); - Client.renderer.renderSignPictureBase(GuiPacketWait.this.task.entity, -0.5D, -0.75D, -0.5D, 0.0F, 1f); + Client.renderer.translateBase(GuiPAAS.this.task.entity, -0.5D, -0.75D, -0.5D, -1f); + Client.renderer.renderSignPictureBase(GuiPAAS.this.task.entity, -0.5D, -0.75D, -0.5D, 0.0F, 1f); glPopMatrix(); } }); @@ -78,15 +79,15 @@ public void draw(final WEvent ev, final Area pgp, final Point p, final float fra add(new MLabel(new RArea(Coord.left(15), Coord.right(15), Coord.top(-f), Coord.bottom(+f)), "") { @Override - public String getText() { - return String.format("Please Wait ( %d / %d letters )", c, max); + public void update(final WEvent ev, final Area pgp, final Point p) { + setText(I18n.format("signpic.gui.paas.count", String.format("%d", c), String.format("%d", max))); } }); add(new MLabel(new RArea(Coord.left(15), Coord.right(15), Coord.top(+f), Coord.bottom(-f)), "") { @Override - public String getText() { - return String.format("Esc for Cancel ( %.2f / %.2f seconds )", GuiPacketWait.this.task.timer.getTime(), GuiPacketWait.this.task.limit / 1000f); + public void update(final WEvent ev, final Area pgp, final Point p) { + setText(I18n.format("signpic.gui.paas.time", String.format("%.1f", GuiPAAS.this.task.timer.getTime()), String.format("%.1f", GuiPAAS.this.task.limit / 1000f))); } }); } @@ -94,14 +95,14 @@ public String getText() { @Override public void update(final WEvent ev, final Area pgp, final Point p) { if (this.close) { - if (!GuiPacketWait.this.task.tick()) { - this.c = (int) (GuiPacketWait.this.task.timer.getTime() * 1000 / GuiPacketWait.this.task.limit * this.max); + if (!GuiPAAS.this.task.tick()) { + this.c = (int) (GuiPAAS.this.task.timer.getTime() * 1000 / GuiPAAS.this.task.limit * this.max); if (this.cursor != this.c) { - final EntryId id = new EntryId(StringUtils.substring(GuiPacketWait.this.task.id.id(), 0, this.c)); + final EntryId id = new EntryId(StringUtils.substring(GuiPAAS.this.task.id.id(), 0, this.c)); final int last = id.getLastLine(); - id.toEntity(GuiPacketWait.this.task.entity); - GuiPacketWait.this.task.entity.lineBeingEdited = last; - final TileEntity e1 = Client.mc.theWorld.getTileEntity(GuiPacketWait.this.task.entity.xCoord, GuiPacketWait.this.task.entity.yCoord, GuiPacketWait.this.task.entity.zCoord); + id.toEntity(GuiPAAS.this.task.entity); + GuiPAAS.this.task.entity.lineBeingEdited = last; + final TileEntity e1 = Client.mc.theWorld.getTileEntity(GuiPAAS.this.task.entity.xCoord, GuiPAAS.this.task.entity.yCoord, GuiPAAS.this.task.entity.zCoord); if (e1 instanceof TileEntitySign) { final TileEntitySign tileSign = (TileEntitySign) e1; id.toEntity(tileSign); diff --git a/src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGui.java b/src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGui.java new file mode 100644 index 00000000..c90d6fd7 --- /dev/null +++ b/src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGui.java @@ -0,0 +1,52 @@ +package com.kamesuta.mc.signpic.gui.config; +import java.util.ArrayList; +import java.util.List; + +import com.kamesuta.mc.signpic.Config; +import com.kamesuta.mc.signpic.Reference; + +import cpw.mods.fml.client.config.GuiConfig; +import cpw.mods.fml.client.config.IConfigElement; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.common.config.ConfigElement; + +public class ConfigGui extends GuiConfig +{ + + public ConfigGui( final GuiScreen parent ) + { + super( parent, getConfigElements(), Reference.MODID, false, false, GuiConfig.getAbridgedConfigPath( Config.instance.getFilePath() ) ); + } + + @SuppressWarnings("rawtypes") + private static List getConfigElements() + { + final List list = new ArrayList(); + + for( final String cat : Config.instance.getCategoryNames() ) + { + if( cat.equals( "versionchecker" ) ) + { + continue; + } + + if( cat.equals( "settings" ) ) + { + continue; + } + + final ConfigCategory cc = Config.instance.getCategory( cat ); + + if( cc.isChild() ) + { + continue; + } + + final ConfigElement ce = new ConfigElement( cc ); + list.add( ce ); + } + + return list; + } +} \ No newline at end of file diff --git a/src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGuiFactory.java b/src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGuiFactory.java new file mode 100644 index 00000000..8b88b8a4 --- /dev/null +++ b/src/main/java/com/kamesuta/mc/signpic/gui/config/ConfigGuiFactory.java @@ -0,0 +1,35 @@ +package com.kamesuta.mc.signpic.gui.config; +import java.util.Set; + +import cpw.mods.fml.client.IModGuiFactory; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; + + +public class ConfigGuiFactory implements IModGuiFactory +{ + + @Override + public void initialize( final Minecraft minecraftInstance ) + { + + } + + @Override + public Class mainConfigGuiClass() + { + return ConfigGui.class; + } + + @Override + public Set runtimeGuiCategories() + { + return null; + } + + @Override + public RuntimeOptionGuiHandler getHandlerFor( final RuntimeOptionCategoryElement element ) + { + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/kamesuta/mc/signpic/handler/CoreHandler.java b/src/main/java/com/kamesuta/mc/signpic/handler/CoreHandler.java index 712db04f..2044dee7 100644 --- a/src/main/java/com/kamesuta/mc/signpic/handler/CoreHandler.java +++ b/src/main/java/com/kamesuta/mc/signpic/handler/CoreHandler.java @@ -3,12 +3,14 @@ import org.lwjgl.util.Timer; import com.kamesuta.mc.signpic.Client; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.EntryManager; import com.kamesuta.mc.signpic.entry.EntrySlot; import com.kamesuta.mc.signpic.entry.content.ContentManager; import com.kamesuta.mc.signpic.information.InformationChecker; import com.kamesuta.mc.signpic.render.SignPicRender; +import cpw.mods.fml.client.event.ConfigChangedEvent; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.InputEvent; @@ -22,6 +24,7 @@ import net.minecraftforge.common.MinecraftForge; public class CoreHandler { + public final Config configHandler = Config.instance; public final KeyHandler keyHandler = new KeyHandler(); public final SignHandler signHandler = new SignHandler(); public final EntryManager signEntryManager = EntryManager.instance; @@ -72,6 +75,11 @@ public void onText(final RenderGameOverlayEvent.Text event) { this.renderHandler.onText(event); } + @SubscribeEvent + public void onConfigChanged(final ConfigChangedEvent.OnConfigChangedEvent eventArgs) { + this.configHandler.onConfigChanged(eventArgs); + } + @SubscribeEvent public void onTick(final ClientTickEvent event) { if (event.phase == Phase.END) { diff --git a/src/main/java/com/kamesuta/mc/signpic/handler/SignHandler.java b/src/main/java/com/kamesuta/mc/signpic/handler/SignHandler.java index 225f93f3..8ff9323c 100644 --- a/src/main/java/com/kamesuta/mc/signpic/handler/SignHandler.java +++ b/src/main/java/com/kamesuta/mc/signpic/handler/SignHandler.java @@ -5,12 +5,10 @@ import com.kamesuta.mc.signpic.Reference; import com.kamesuta.mc.signpic.entry.Entry; import com.kamesuta.mc.signpic.entry.EntryId; -import com.kamesuta.mc.signpic.gui.GuiPacketWait; import com.kamesuta.mc.signpic.mode.CurrentMode; import com.kamesuta.mc.signpic.preview.SignEntity; import com.kamesuta.mc.signpic.util.ChatBuilder; import com.kamesuta.mc.signpic.util.Sign; -import com.kamesuta.mc.signpic.util.Sign.SendPacketTask; import net.minecraft.client.gui.inventory.GuiEditSign; import net.minecraft.client.resources.I18n; @@ -44,7 +42,7 @@ public void onSign(final GuiOpenEvent event) { try { final GuiEditSign ges = (GuiEditSign) event.gui; final TileEntitySign tileSign = (TileEntitySign) f.get(ges); - Client.mc.displayGuiScreen(new GuiPacketWait(new SendPacketTask(CurrentMode.instance.getEntryId(), tileSign))); + Sign.placeSign(CurrentMode.instance.getEntryId(), tileSign); event.setCanceled(true); if (!CurrentMode.instance.isState(CurrentMode.State.CONTINUE)) { CurrentMode.instance.setMode(); diff --git a/src/main/java/com/kamesuta/mc/signpic/image/ImageIOLoader.java b/src/main/java/com/kamesuta/mc/signpic/image/ImageIOLoader.java index aca4cf17..14763ef8 100644 --- a/src/main/java/com/kamesuta/mc/signpic/image/ImageIOLoader.java +++ b/src/main/java/com/kamesuta/mc/signpic/image/ImageIOLoader.java @@ -18,6 +18,7 @@ import org.apache.commons.io.IOUtils; import com.google.common.collect.Lists; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.content.Content; import com.kamesuta.mc.signpic.entry.content.ContentLocation; import com.kamesuta.mc.signpic.entry.content.ContentStateType; @@ -30,7 +31,9 @@ import net.minecraft.util.ResourceLocation; public class ImageIOLoader { - public static final ImageSize MAX_SIZE = new ImageSize().setSize(512, 512); + public static final ImageSize MAX_SIZE = new ImageSize().setSize( + ((Config.instance.imageWidthLimit > 0) ? Config.instance.imageWidthLimit : ImageSize.unknownSize), + ((Config.instance.imageHeightLimit > 0) ? Config.instance.imageHeightLimit : ImageSize.unknownSize)); protected Content content; protected InputStream input; @@ -62,7 +65,7 @@ public ImageTextures load() throws IOException { this.content.state.setType(ContentStateType.LOADING); ImageTextures textures; - if (reader.getFormatName()=="gif") { + if (Config.instance.imageAnimationGif && reader.getFormatName()=="gif") { textures = loadGif(data); } else { textures = loadImage(reader, imagestream); diff --git a/src/main/java/com/kamesuta/mc/signpic/image/RemoteImage.java b/src/main/java/com/kamesuta/mc/signpic/image/RemoteImage.java index 2201d010..a8a8b35e 100644 --- a/src/main/java/com/kamesuta/mc/signpic/image/RemoteImage.java +++ b/src/main/java/com/kamesuta/mc/signpic/image/RemoteImage.java @@ -7,6 +7,7 @@ import com.kamesuta.mc.signpic.Client; import com.kamesuta.mc.signpic.entry.content.Content; +import com.kamesuta.mc.signpic.entry.content.ContentCapacityOverException; import com.kamesuta.mc.signpic.entry.content.ContentDownloader; import com.kamesuta.mc.signpic.entry.content.ContentManager; import com.kamesuta.mc.signpic.entry.content.ContentStateType; @@ -38,6 +39,9 @@ public void onAsyncProcess() { } catch (final URISyntaxException e) { this.content.state.setType(ContentStateType.ERROR); this.content.state.setMessage(I18n.format("signpic.advmsg.invalidurl")); + } catch (final ContentCapacityOverException e) { + this.content.state.setType(ContentStateType.ERROR); + this.content.state.setMessage(I18n.format("signpic.advmsg.capacityover")); } catch (final InvaildImageException e) { this.content.state.setType(ContentStateType.ERROR); this.content.state.setMessage(I18n.format("signpic.advmsg.invalidimage")); diff --git a/src/main/java/com/kamesuta/mc/signpic/image/meta/ImageSize.java b/src/main/java/com/kamesuta/mc/signpic/image/meta/ImageSize.java index a10e1d81..40572e5e 100644 --- a/src/main/java/com/kamesuta/mc/signpic/image/meta/ImageSize.java +++ b/src/main/java/com/kamesuta/mc/signpic/image/meta/ImageSize.java @@ -80,7 +80,10 @@ else if (imagesize.vaildHeight()) } public ImageSize setSize(final ImageSizes s, final float rawWidth, final float rawHeight, final float maxWidth, final float maxHeight) { - s.size(this, rawWidth, rawHeight, maxWidth, maxHeight); + if ((rawWidth == unknownSize && maxWidth == unknownSize) || (rawHeight == unknownSize && maxHeight == unknownSize)) + throw new IllegalArgumentException("No Size Defined"); + s.size(this, rawWidth != unknownSize ? rawWidth : maxWidth, rawHeight != unknownSize ? rawHeight : maxHeight, + maxWidth != unknownSize ? maxWidth : rawWidth, maxHeight != unknownSize ? maxHeight : rawHeight); return this; } diff --git a/src/main/java/com/kamesuta/mc/signpic/information/InformationChecker.java b/src/main/java/com/kamesuta/mc/signpic/information/InformationChecker.java index 376d29e6..518fec80 100644 --- a/src/main/java/com/kamesuta/mc/signpic/information/InformationChecker.java +++ b/src/main/java/com/kamesuta/mc/signpic/information/InformationChecker.java @@ -4,6 +4,7 @@ import org.apache.commons.lang3.math.NumberUtils; import com.kamesuta.mc.signpic.Client; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.Reference; import com.kamesuta.mc.signpic.handler.CoreEvent; import com.kamesuta.mc.signpic.util.ChatBuilder; @@ -30,29 +31,25 @@ public void onTick() { final EntityPlayer player = Client.mc.thePlayer; if(this.doneChecking && player != null && !this.triedToWarnPlayer) { final String lang = Client.mc.gameSettings.language; - if (!StringUtils.equals(Reference.VERSION, "${version}")) { + if (Config.instance.informationNotice && !StringUtils.equals(Reference.VERSION, "${version}")) { try { final String[] client = Reference.VERSION.split("\\."); - if (client.length>=2) { + if (client.length>=3) { final int clientBuild1 = Integer.parseInt(client[0]); final int clientBuild2 = Integer.parseInt(client[1]); + final int clientBuild3 = Integer.parseInt(client[2]); boolean betaneedupdate = false; - if (this.unstableVersion!=null && this.unstableVersion.version!=null) { - if (client.length>=4 &&StringUtils.equals(client[3], "beta")) { - if (NumberUtils.isNumber(client[2])) { - final int clientBuild3 = NumberUtils.toInt(client[2]); - final String[] beta = this.unstableVersion.version.split("\\."); - if (beta.length>=4 &&StringUtils.equals(beta[3], "beta")) { - if (NumberUtils.isNumber(beta[0]) && NumberUtils.isNumber(beta[1]) && NumberUtils.isNumber(beta[2])) { - final int betaBuild1 = NumberUtils.toInt(beta[0]); - final int betaBuild2 = NumberUtils.toInt(beta[1]); - final int betaBuild3 = NumberUtils.toInt(beta[2]); - betaneedupdate = (betaBuild1 > clientBuild1) || - (betaBuild1 == clientBuild1 && betaBuild2 > clientBuild2) || - (betaBuild1 == clientBuild1 && betaBuild2 == clientBuild2 && betaBuild3 > clientBuild3); - } - } + if (Config.instance.informationJoinBeta && this.unstableVersion!=null && this.unstableVersion.version!=null) { + final String[] beta = this.unstableVersion.version.split("\\."); + if (beta.length>=4 &&StringUtils.equals(beta[3], "beta")) { + if (NumberUtils.isNumber(beta[0]) && NumberUtils.isNumber(beta[1]) && NumberUtils.isNumber(beta[2])) { + final int betaBuild1 = NumberUtils.toInt(beta[0]); + final int betaBuild2 = NumberUtils.toInt(beta[1]); + final int betaBuild3 = NumberUtils.toInt(beta[2]); + betaneedupdate = (betaBuild1 > clientBuild1) || + (betaBuild1 == clientBuild1 && betaBuild2 > clientBuild2) || + (betaBuild1 == clientBuild1 && betaBuild2 == clientBuild2 && betaBuild3 > clientBuild3); } } } @@ -63,12 +60,15 @@ public void onTick() { if (this.onlineVersion!=null && this.onlineVersion.version!=null) { final String[] online = this.onlineVersion.version.split("\\."); - if (online.length>=2) { + if (online.length>=3) { boolean needupdate = false; if (!betaneedupdate) { final int onlineBuild1 = Integer.parseInt(online[0]); final int onlineBuild2 = Integer.parseInt(online[1]); - needupdate = (onlineBuild1 > clientBuild1) || (onlineBuild1 == clientBuild1 && onlineBuild2 > clientBuild2); + final int onlineBuild3 = Integer.parseInt(online[2]); + needupdate = (onlineBuild1 > clientBuild1) || + (onlineBuild1 == clientBuild1 && onlineBuild2 > clientBuild2) || + (onlineBuild1 == clientBuild1 && onlineBuild2 == clientBuild2 && onlineBuild3 > clientBuild3); } if(betaneedupdate || needupdate) { diff --git a/src/main/java/com/kamesuta/mc/signpic/proxy/ClientProxy.java b/src/main/java/com/kamesuta/mc/signpic/proxy/ClientProxy.java index f2b602b6..f6e7c304 100644 --- a/src/main/java/com/kamesuta/mc/signpic/proxy/ClientProxy.java +++ b/src/main/java/com/kamesuta/mc/signpic/proxy/ClientProxy.java @@ -58,8 +58,6 @@ public void preInit(final FMLPreInitializationEvent event) { Client.mcDir = mcdir; Client.signpicDir = signpicdir; Client.signpicCacheDir = cachedir; - Client.configDir = event.getModConfigurationDirectory(); - Client.configFile = event.getSuggestedConfigurationFile(); Client.modDir = new File(mcdir, "mods"); Client.modFile = event.getSourceFile(); diff --git a/src/main/java/com/kamesuta/mc/signpic/render/CustomTileEntitySignRenderer.java b/src/main/java/com/kamesuta/mc/signpic/render/CustomTileEntitySignRenderer.java index f5e5748e..e41edf18 100644 --- a/src/main/java/com/kamesuta/mc/signpic/render/CustomTileEntitySignRenderer.java +++ b/src/main/java/com/kamesuta/mc/signpic/render/CustomTileEntitySignRenderer.java @@ -3,6 +3,7 @@ import static org.lwjgl.opengl.GL11.*; import com.kamesuta.mc.signpic.Client; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.Entry; import com.kamesuta.mc.signpic.entry.EntryId; import com.kamesuta.mc.signpic.entry.content.Content; @@ -116,7 +117,7 @@ public void renderSignPictureBase(final TileEntitySign tile, final double x, fin if (entry.isValid()) { if (CurrentMode.instance.isState(CurrentMode.State.SEE)) { RenderHelper.startTexture(); - glColor4f(1f, 1f, 1f, opacity * .5f); + glColor4f(1f, 1f, 1f, opacity * Config.instance.renderSeeOpacity); super.renderTileEntityAt(tile, x, y, z, partialTicks); } diff --git a/src/main/java/com/kamesuta/mc/signpic/render/SignPicRender.java b/src/main/java/com/kamesuta/mc/signpic/render/SignPicRender.java index 09f6bda5..edeccb4b 100644 --- a/src/main/java/com/kamesuta/mc/signpic/render/SignPicRender.java +++ b/src/main/java/com/kamesuta/mc/signpic/render/SignPicRender.java @@ -4,6 +4,7 @@ import com.kamesuta.mc.bnnwidget.WGui; import com.kamesuta.mc.signpic.Client; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.Entry; import com.kamesuta.mc.signpic.entry.EntryId; import com.kamesuta.mc.signpic.entry.content.Content; @@ -29,10 +30,10 @@ public SignPicRender() { @CoreEvent public void onRender(final RenderWorldLastEvent event) { - float opacity = 0.7f; + float opacity = Config.instance.renderPreviewFixedOpacity; if (CurrentMode.instance.isMode(CurrentMode.Mode.SETPREVIEW) || CurrentMode.instance.isMode(CurrentMode.Mode.PLACE)) { Sign.preview.capturePlace(); - opacity *= 0.7f; + opacity = Config.instance.renderPreviewFloatedOpacity; } if (CurrentMode.instance.isState(CurrentMode.State.PREVIEW)) { if (Sign.preview.isRenderable() && Sign.preview.isVisible()) { diff --git a/src/main/java/com/kamesuta/mc/signpic/util/Sign.java b/src/main/java/com/kamesuta/mc/signpic/util/Sign.java index 4012173f..be2a48e4 100644 --- a/src/main/java/com/kamesuta/mc/signpic/util/Sign.java +++ b/src/main/java/com/kamesuta/mc/signpic/util/Sign.java @@ -3,8 +3,10 @@ import org.lwjgl.util.Timer; import com.kamesuta.mc.signpic.Client; +import com.kamesuta.mc.signpic.Config; import com.kamesuta.mc.signpic.entry.EntryId; import com.kamesuta.mc.signpic.entry.EntryIdBuilder; +import com.kamesuta.mc.signpic.gui.GuiPAAS; import com.kamesuta.mc.signpic.preview.SignEntity; import net.minecraft.client.network.NetHandlerPlayClient; @@ -30,6 +32,13 @@ public static void sendSign(final EntryId entryId, final TileEntitySign sourceen sourceentity.setEditable(true); } + public static void placeSign(final EntryId entryId, final TileEntitySign sourceentity) { + if (Config.instance.multiplayPAAS && !Client.mc.isSingleplayer()) + Client.mc.displayGuiScreen(new GuiPAAS(new SendPacketTask(entryId, sourceentity))); + else + sendSign(entryId, sourceentity); + } + public static class SendPacketTask { public final long limit; public final EntryId id; @@ -58,15 +67,8 @@ public boolean tick() { return false; } - /** Fastest time "possible" estimate for an empty sign. */ - private static long minEditTime = 150; - /** Minimum time needed to add one extra line (not the first). */ - private static long minLineTime = 50; - /** Minimum time needed to type a character. */ - private static long minCharTime = 50; - - public static long getExpectedEditTime(final String[] lines, final boolean skipEmpty) { - long expected = minEditTime; + private static long getExpectedEditTime(final String[] lines, final boolean skipEmpty) { + long expected = Config.instance.multiplayPAASMinEditTime; int n = 0; for (String line : lines){ if (line != null){ @@ -74,7 +76,7 @@ public static long getExpectedEditTime(final String[] lines, final boolean skipE if (!line.isEmpty()){ final int chars = line.length(); n += 1; - expected += minCharTime * chars; + expected += Config.instance.multiplayPAASMinCharTime * chars; } } } @@ -82,7 +84,7 @@ public static long getExpectedEditTime(final String[] lines, final boolean skipE return 0; } if (n > 1){ - expected += minLineTime * n; + expected += Config.instance.multiplayPAASMinLineTime * n; } return expected; } diff --git a/src/main/resources/assets/signpic/lang/en_US.lang b/src/main/resources/assets/signpic/lang/en_US.lang index f80ad552..49e8f4ee 100644 --- a/src/main/resources/assets/signpic/lang/en_US.lang +++ b/src/main/resources/assets/signpic/lang/en_US.lang @@ -21,6 +21,7 @@ signpic.key.category=Sign Picture signpic.key.gui=Open GUI # GUI +## Sign Editor signpic.gui.editor.see=View Sign signpic.gui.editor.preview=Preview signpic.gui.editor.continue=Continue @@ -28,7 +29,7 @@ signpic.gui.editor.load=Load signpic.gui.editor.place=Place signpic.gui.editor.cancel=Cancel signpic.gui.editor.textfield=Place URL Here! -## Size +### Size signpic.gui.editor.size.category=Size signpic.gui.editor.size.width=W signpic.gui.editor.size.height=H @@ -36,7 +37,7 @@ signpic.gui.editor.size.width.neg=- signpic.gui.editor.size.width.pos=+ signpic.gui.editor.size.height.neg=- signpic.gui.editor.size.height.pos=+ -## Offset +### Offset signpic.gui.editor.offset.category=Offset signpic.gui.editor.offset.x=X signpic.gui.editor.offset.x.neg=⇦ @@ -47,7 +48,7 @@ signpic.gui.editor.offset.y.pos=⇧ signpic.gui.editor.offset.z=Z signpic.gui.editor.offset.z.neg=↗ signpic.gui.editor.offset.z.pos=↙ -## Rotation +### Rotation signpic.gui.editor.rotation.category=Rotation signpic.gui.editor.rotation.up=↑ signpic.gui.editor.rotation.down=↓ @@ -58,6 +59,9 @@ signpic.gui.editor.rotation.remove=- signpic.gui.editor.rotation.add=+ signpic.gui.editor.rotation.neg=- signpic.gui.editor.rotation.pos=+ +## Prevent Anti-AutoSign +signpic.gui.paas.count=Please Wait ( %d / %d letters ) +signpic.gui.paas.time=Esc for Cancel ( %.2f / %.2f seconds ) # Image State signpic.state.init=Waiting... @@ -72,6 +76,7 @@ signpic.state.error=ERROR # Image State Additional Message signpic.advmsg.invalidurl=Invalid URL +signpic.advmsg.capacityover=CapacityOver signpic.advmsg.invalidimage=Invalid Image signpic.advmsg.ioerror=Failed to Read: §7%s signpic.advmsg.unknown=Unknown Error: §7%s diff --git a/src/main/resources/assets/signpic/lang/ja_JP.lang b/src/main/resources/assets/signpic/lang/ja_JP.lang index bba1ae0d..4b1fa9aa 100644 --- a/src/main/resources/assets/signpic/lang/ja_JP.lang +++ b/src/main/resources/assets/signpic/lang/ja_JP.lang @@ -8,6 +8,7 @@ signpic.over.mode.setpreview=ブロックをクリックしてプレビュー位 signpic.chat.error.place=[§6SignPicture§r] 申し訳ございませんがエラーが発生したためこの機能をご利用になることができません。 # GUI +## Sign Editor signpic.gui.editor.see=実体表示 signpic.gui.editor.preview=プレビュー signpic.gui.editor.continue=連続 @@ -15,14 +16,17 @@ signpic.gui.editor.load=ロード signpic.gui.editor.place=設置 signpic.gui.editor.cancel=キャンセル signpic.gui.editor.textfield=ここにURLを入力! -## Size +### Size signpic.gui.editor.size.category=サイズ signpic.gui.editor.size.width=幅 signpic.gui.editor.size.height=高さ -## Offset +### Offset signpic.gui.editor.offset.category=オフセット -## Rotation +### Rotation signpic.gui.editor.rotation.category=回転 +## Prevent Anti-AutoSign +signpic.gui.paas.count=しばらくお待ちください ( %s / %s 文字 ) +signpic.gui.paas.time=Esc でキャンセル ( %s / %s 秒 ) # Image State signpic.state.init=待機中... @@ -37,6 +41,7 @@ signpic.state.error=エラー # Image State Additional Message signpic.advmsg.invalidurl=不正なURL +signpic.advmsg.capacityover=容量オーバー signpic.advmsg.invalidimage=不正な画像 signpic.advmsg.ioerror=ファイル読み込み失敗: §7%s signpic.advmsg.unknown=不明なエラー: §7%s