From 7515585c02d875572722514d03e7b244b629f608 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Fri, 18 Jan 2019 16:57:44 +0800 Subject: [PATCH 01/16] Fix Using Scattering Bomb has chance to crash the game, close #636 --- .../meltdowner/skill/SBNetDelegate.java | 33 +++++++ .../cn/academy/network/MessageSBEffect.java | 85 ------------------- .../cn/academy/network/NetworkManager.java | 15 ---- .../meltdowner/skill/ScatterBomb.scala | 15 +++- 4 files changed, 45 insertions(+), 103 deletions(-) create mode 100644 src/main/java/cn/academy/ability/vanilla/meltdowner/skill/SBNetDelegate.java delete mode 100644 src/main/java/cn/academy/network/MessageSBEffect.java diff --git a/src/main/java/cn/academy/ability/vanilla/meltdowner/skill/SBNetDelegate.java b/src/main/java/cn/academy/ability/vanilla/meltdowner/skill/SBNetDelegate.java new file mode 100644 index 000000000..0bc83f199 --- /dev/null +++ b/src/main/java/cn/academy/ability/vanilla/meltdowner/skill/SBNetDelegate.java @@ -0,0 +1,33 @@ +package cn.academy.ability.vanilla.meltdowner.skill; + +import cn.academy.entity.EntityMdRaySmall; +import cn.lambdalib2.registry.StateEventCallback; +import cn.lambdalib2.s11n.network.NetworkMessage.Listener; +import cn.lambdalib2.s11n.network.NetworkS11n; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public enum SBNetDelegate { + INSTANCE; + public static final String MSG_EFFECT = "eff"; + + @StateEventCallback + private static void init(FMLInitializationEvent ev) { + NetworkS11n.addDirectInstance(SBNetDelegate.INSTANCE); + } + + @SideOnly(Side.CLIENT) + @Listener(channel = MSG_EFFECT, side = Side.CLIENT) + private void hSpawnEffect(Vec3d start, Vec3d end) { + EntityPlayer player = Minecraft.getMinecraft().player; + EntityMdRaySmall raySmall = new EntityMdRaySmall(player.world); + raySmall.setFromTo(start, end); + raySmall.viewOptimize = false; + player.world.spawnEntity(raySmall); + } + +} diff --git a/src/main/java/cn/academy/network/MessageSBEffect.java b/src/main/java/cn/academy/network/MessageSBEffect.java deleted file mode 100644 index b14c38940..000000000 --- a/src/main/java/cn/academy/network/MessageSBEffect.java +++ /dev/null @@ -1,85 +0,0 @@ -package cn.academy.network; - -import cn.academy.entity.EntityMdRaySmall; -import io.netty.buffer.ByteBuf; -import net.minecraft.client.Minecraft; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** - * Created by Paindar on 2017/2/16. - */ -public class MessageSBEffect implements IMessage -{ - public static class Handler implements IMessageHandler - { - @Override - @SideOnly(Side.CLIENT) - public IMessage onMessage(MessageSBEffect msg, MessageContext ctx) - { - if (ctx.side == Side.CLIENT) - { - EntityPlayer player=Minecraft.getMinecraft().player; - EntityMdRaySmall raySmall = new EntityMdRaySmall(player.world); - raySmall.setFromTo(msg.strX, msg.strY,msg.strZ, msg.endX, msg.endY, msg.endZ); - raySmall.viewOptimize = false; - player.world.spawnEntity(raySmall); - } - - return null; - } - } - - Vec3d str,end; - NBTTagCompound nbt; - - public MessageSBEffect(){} - - public double strX,strY,strZ; - public double endX,endY,endZ; - - public MessageSBEffect(Vec3d str, Vec3d end) { - strX=str.x; - strY=str.y; - strZ=str.z; - endX=end.x; - endY=end.y; - endZ=end.z; - } - - /** - * Convert from the supplied buffer into your specific message type - * - * @param buf - */ - @Override - public void fromBytes(ByteBuf buf) { - strX=buf.readDouble(); - strY=buf.readDouble(); - strZ=buf.readDouble(); - endX=buf.readDouble(); - endY=buf.readDouble(); - endZ=buf.readDouble(); - } - - /** - * Deconstruct your message into the supplied byte buffer - * - * @param buf - */ - @Override - public void toBytes(ByteBuf buf) { - buf.writeDouble(strX); - buf.writeDouble(strY); - buf.writeDouble(strZ); - buf.writeDouble(endX); - buf.writeDouble(endY); - buf.writeDouble(endZ); - } -} \ No newline at end of file diff --git a/src/main/java/cn/academy/network/NetworkManager.java b/src/main/java/cn/academy/network/NetworkManager.java index c77f76175..bfc7ec804 100644 --- a/src/main/java/cn/academy/network/NetworkManager.java +++ b/src/main/java/cn/academy/network/NetworkManager.java @@ -30,7 +30,6 @@ public class NetworkManager public static void init(FMLPreInitializationEvent event) { registerMessage(MessageConfig.Handler.class, MessageConfig.class, Side.CLIENT); - registerMessage(MessageSBEffect.Handler.class, MessageSBEffect.class, Side.CLIENT); } private static void registerMessage( @@ -50,18 +49,4 @@ public static void sendTo(Config cfg, EntityPlayerMP player) } } - public static void sendSBEffectToClient(EntityPlayer speller, Vec3d str, Vec3d end) - { - List list= WorldUtils.getEntities(speller, 25, EntitySelectors.player()); - for(Entity e:list) - { - if(!speller.getEntityWorld().isRemote) - { - MessageSBEffect msg = new MessageSBEffect(str,end); - instance.sendTo(msg, (EntityPlayerMP)speller); - } - else - throw new IllegalStateException("Wrong context side!"); - } - } } \ No newline at end of file diff --git a/src/main/scala/cn/academy/ability/vanilla/meltdowner/skill/ScatterBomb.scala b/src/main/scala/cn/academy/ability/vanilla/meltdowner/skill/ScatterBomb.scala index ffc9b3c5a..e695a1d74 100644 --- a/src/main/scala/cn/academy/ability/vanilla/meltdowner/skill/ScatterBomb.scala +++ b/src/main/scala/cn/academy/ability/vanilla/meltdowner/skill/ScatterBomb.scala @@ -6,10 +6,13 @@ import java.util.function.Predicate import cn.academy.ability.Skill import cn.academy.ability.context.{ClientRuntime, Context} import cn.academy.client.render.util.ACRenderingHelper -import cn.academy.entity.EntityMdBall +import cn.academy.entity.{EntityMdBall, EntityMdRaySmall} import cn.academy.network.NetworkManager +import cn.lambdalib2.registry.StateEventCallback import cn.lambdalib2.s11n.network.NetworkMessage.Listener +import cn.lambdalib2.s11n.network.{NetworkMessage, NetworkS11n, NetworkS11nType, TargetPoints} import cn.lambdalib2.util._ +import net.minecraft.client.Minecraft import net.minecraftforge.fml.relauncher.{Side, SideOnly} import net.minecraft.entity.{Entity, EntityLiving, EntityLivingBase} import net.minecraft.entity.player.EntityPlayer @@ -104,7 +107,13 @@ class SBContext(p: EntityPlayer) extends Context(p, ScatterBomb) { traceResult.entityHit.hurtResistantTime = -1 MDDamageHelper.attack(ctx, traceResult.entityHit, getDamage(exp)) } - NetworkManager.sendSBEffectToClient(player, new Vec3d(ball.posX, ball.posY, ball.posZ), new Vec3d(dest.x,dest.y,dest.z)) + NetworkMessage.sendToAllAround( + TargetPoints.convert(player, 25), + SBNetDelegate.INSTANCE, + SBNetDelegate.MSG_EFFECT, + ball.getPositionVector, + dest + ) ball.setDead() } ctx.addSkillExp(0.001f * balls.size) @@ -119,4 +128,4 @@ class SBContext(p: EntityPlayer) extends Context(p, ScatterBomb) { begin.add(look.scale(RAY_RANGE)) } -} \ No newline at end of file +} From 95a9d24b14d6d467cb009047a3c61c2975dec252 Mon Sep 17 00:00:00 2001 From: voidcl Date: Wed, 6 Mar 2019 19:35:42 +0800 Subject: [PATCH 02/16] Add a 10s delay to analysis system message sender , fix the time zone problem and solve the ip problem . close #755 --- .../analyticUtil/AnalyticDataListener.java | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/main/java/cn/academy/analyticUtil/AnalyticDataListener.java b/src/main/java/cn/academy/analyticUtil/AnalyticDataListener.java index 7882447de..5b87c7f3d 100644 --- a/src/main/java/cn/academy/analyticUtil/AnalyticDataListener.java +++ b/src/main/java/cn/academy/analyticUtil/AnalyticDataListener.java @@ -21,9 +21,12 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.TimeZone; // Collects some **anonymous** analytics data // What we collect: a unique hash of user, location, in-mod action (Level-up, use ability, etc.) @@ -52,7 +55,7 @@ public void loginListener(PlayerEvent.PlayerLoggedInEvent event){ serverSource = new AnalyticDto(); serverSource.setVersion(AcademyCraft.VERSION); serverSource.setUuidName("server"); - serverSource.setStartTime(new Date().getTime()); + serverSource.setStartTime(UTCZeroTime()); String[] ipArray =serverIp.split(" "); if (ipArray.length < 6) { serverSource.initNaNIPInfo(); @@ -63,7 +66,13 @@ public void loginListener(PlayerEvent.PlayerLoggedInEvent event){ serverSource.setCity(ipArray[5]); } } - NetworkMessage.sendTo(event.player,this,CHANNEL,event.player,serverIp); + Thread delaySender = new DelaySender(event.player,serverIp); + delaySender.start();//avoid sending message to the client thread before it hasn't been initialized + } + + @NetworkMessage.Listener(channel = "delay",side = Side.SERVER) + public void serverGetter(EntityPlayer player,String serverIp){ + NetworkMessage.sendTo(player,this,CHANNEL,player,serverIp); } //on Client @@ -88,7 +97,7 @@ public void serverIpCollector(String ipInfo,EntityPlayer player,Boolean isServer AnalyticDto playerData = new AnalyticDto(); playerData.setVersion(AcademyCraft.VERSION); playerData.setUuidName(SHA(player.getUniqueID()+player.getName())); - playerData.setStartTime(new Date().getTime()); + playerData.setStartTime(UTCZeroTime()); String[] ipArray = ipInfo.split(" "); if (ipArray.length < 6) { playerData.initNaNIPInfo(); @@ -107,6 +116,9 @@ public void serverIpCollector(String ipInfo,EntityPlayer player,Boolean isServer public void skillListener(AnalyticSkillEvent event){ EntityPlayer targetPlayer = event.getPlayer(); String uuid = SHA(targetPlayer.getUniqueID()+targetPlayer.getName()); + for(String temp:sourceMap.keySet()){ + System.out.println(temp); + } if(sourceMap.containsKey(uuid)){ Map countMap = sourceMap.get(uuid).getCountMap(); if(countMap.containsKey(event.getSkillName())){ @@ -158,6 +170,7 @@ private String getCurrentIPinfo(){ try { URL object = new URL("https://myip.ipip.net"); HttpURLConnection con = (HttpURLConnection)object.openConnection(); + con.setRequestProperty("User-Agent",""); BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8)); String line = null; StringBuilder sb = new StringBuilder(); @@ -199,4 +212,31 @@ private String SHA(final String strText){ return strResult; } + private long UTCZeroTime(){ + SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("GMT+0:00")); + String currDate = df.format(new Date()); + Timestamp timestamp = Timestamp.valueOf(currDate); + return timestamp.getTime(); + } + +} + +class DelaySender extends Thread{ + private EntityPlayer player; + private String serverIp; + DelaySender(EntityPlayer player,String serverIp){ + this.player=player; + this.serverIp=serverIp; + } + @Override + public void run() { + try { + Thread.sleep(10000); + NetworkS11n.addDirectInstance(AcademyCraft.analyticDataListener); + NetworkMessage.sendToServer(AcademyCraft.analyticDataListener,"delay",player,serverIp); + }catch (Exception e){ + e.printStackTrace(); + } + } } From fecbc27a2dc9f94dd6a7d73e9f04366556cab6a0 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Mon, 11 Mar 2019 19:27:18 +0800 Subject: [PATCH 03/16] build: Shade LL2 into final jar No LambdaLib2 dep required from now on! --- build.gradle | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 7ad931445..da18b97b9 100644 --- a/build.gradle +++ b/build.gradle @@ -99,7 +99,7 @@ repositories { configurations { provided shade - compile.extendsFrom shade + deobfCompile.extendsFrom shade } // sourceSets.main.compileClasspath += [configurations.provided] @@ -112,7 +112,10 @@ idea { dependencies { - deobfCompile "cn.lambdalib2:LambdaLib2:${config.lambdalib_ver}" + // Shade dependencies + shade "cn.lambdalib2:LambdaLib2:${config.lambdalib_ver}" + + // Optional dependencies deobfCompile "codechicken:CodeChickenLib:1.12.2-${config.ccl_ver}:universal" deobfCompile "mezz.jei:jei_1.12.2:4.8.0.119" //deobfCompile "codechicken:NotEnoughItems:1.12.2-${config.nei_ver}:universal" @@ -167,14 +170,24 @@ compileScala.options.encoding = "UTF-8" task deobfJar(type: Jar, dependsOn: 'jar') { classifier 'dev' from sourceSets.main.output + manifest { + attributes 'FMLCorePluginContainsFMLMod' : 'true' + attributes 'FMLCorePlugin' : 'cn.lambdalib2.CorePlugin' + } } jar { configurations.shade.each { dep -> from(project.zipTree(dep)){ exclude 'META-INF', 'META-INF/**' + exclude 'mcmod.info' + exclude 'pack.mcmeta' } } + manifest { + attributes 'FMLCorePluginContainsFMLMod' : 'true' + attributes 'FMLCorePlugin' : 'cn.lambdalib2.CorePlugin' + } } // http://www.minecraftforge.net/forum/topic/36791-trying-to-shade-dependencies-into-jar/ From 0b354248932b6aabbdeb629ed230c8e29ede41e6 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Mon, 11 Mar 2019 19:30:32 +0800 Subject: [PATCH 04/16] AboutApp: Request donator list from web --- .../cn/academy/client/auxgui/TerminalUI.java | 5 ++ .../java/cn/academy/terminal/DonatorList.java | 80 +++++++++++++++++++ .../cn/academy/terminal/app/AppAbout.java | 20 ++++- .../assets/academy/config/about.conf | 1 + .../resources/assets/academy/lang/en_us.lang | 2 +- .../resources/assets/academy/lang/zh_cn.lang | 2 +- .../resources/assets/academy/lang/zh_tw.lang | 2 +- src/test/java/DonatorListTest.kt | 12 +++ 8 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 src/main/java/cn/academy/terminal/DonatorList.java create mode 100644 src/test/java/DonatorListTest.kt diff --git a/src/main/java/cn/academy/client/auxgui/TerminalUI.java b/src/main/java/cn/academy/client/auxgui/TerminalUI.java index 57647bbdc..ac86c38a8 100644 --- a/src/main/java/cn/academy/client/auxgui/TerminalUI.java +++ b/src/main/java/cn/academy/client/auxgui/TerminalUI.java @@ -2,6 +2,7 @@ import cn.academy.Resources; import cn.academy.client.sound.ACSounds; +import cn.academy.terminal.DonatorList; import cn.academy.util.RegACKeyHandler; import cn.academy.terminal.App; import cn.academy.terminal.AppEnvironment; @@ -105,6 +106,10 @@ public void onEnable() { KeyManager.dynamic.addKeyHandler("terminal_click",KeyManager.MOUSE_LEFT, clickHandler = new LeftClickHandler()); ControlOverrider.override(OVERRIDE_GROUP, KeyManager.MOUSE_LEFT); + + // There is a chance that About App will be opened + // to improve user experience we request that ahead of time + DonatorList.Instance.tryRequest(); } @Override diff --git a/src/main/java/cn/academy/terminal/DonatorList.java b/src/main/java/cn/academy/terminal/DonatorList.java new file mode 100644 index 000000000..4d639e1ba --- /dev/null +++ b/src/main/java/cn/academy/terminal/DonatorList.java @@ -0,0 +1,80 @@ +package cn.academy.terminal; + +import cn.academy.AcademyCraft; +import cn.lambdalib2.util.Debug; +import com.google.gson.Gson; +import net.minecraft.client.Minecraft; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.Event; +import org.apache.commons.io.IOUtils; + +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Collections; +import java.util.List; + +public enum DonatorList { + Instance; + + List _donators = Collections.emptyList(); + + final Gson _gson = new Gson(); + + volatile boolean _requesting = false; + + public boolean isLoaded() { + return _donators.size() > 0; + } + + private class Attributes { + public List list; + } + + private class ResponseData { + public boolean success; + public Attributes attributes; + } + + public List getList() { + return _donators; + } + + public void tryRequest() { + if (!isLoaded() && !_requesting) { + _requesting = true; + new Thread(() -> { + try { + String url = "http://144.34.208.247:8080/lambda/donation/sponsor"; + URLConnection con = new URL(url).openConnection(); + con.setDoInput(true); + + InputStream is = con.getInputStream(); + String text = IOUtils.toString(is, "UTF-8"); + ResponseData rsp = _gson.fromJson(text, ResponseData.class); + + if (rsp.success) { + Debug.assertNotNull(rsp.attributes); + Debug.assertNotNull(rsp.attributes.list); + + // Acknowledge the result in CLIENT thread + Minecraft.getMinecraft().addScheduledTask(() -> { + _donators = rsp.attributes.list; + MinecraftForge.EVENT_BUS.post(new DonatorListRefreshEvent()); + }); + } else { + Debug.error("AcademyCraft failed when requesting donator list."); + if (AcademyCraft.DEBUG_MODE) + Debug.error("Rsp str: " + text); + } + } catch (Exception e) { + if (AcademyCraft.DEBUG_MODE) + Debug.error(e); + } + _requesting = false; + }).run(); + } + } + + public static class DonatorListRefreshEvent extends Event {} +} diff --git a/src/main/java/cn/academy/terminal/app/AppAbout.java b/src/main/java/cn/academy/terminal/app/AppAbout.java index 75b57d6a5..10b78cd94 100644 --- a/src/main/java/cn/academy/terminal/app/AppAbout.java +++ b/src/main/java/cn/academy/terminal/app/AppAbout.java @@ -3,6 +3,8 @@ import cn.academy.Resources; import cn.academy.terminal.App; import cn.academy.terminal.AppEnvironment; +import cn.academy.terminal.DonatorList; +import cn.academy.terminal.DonatorList.DonatorListRefreshEvent; import cn.academy.terminal.RegApp; import cn.lambdalib2.cgui.CGuiScreen; import cn.lambdalib2.cgui.Widget; @@ -26,6 +28,8 @@ import com.typesafe.config.ConfigValue; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.I18n; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.lwjgl.input.Mouse; @@ -229,6 +233,14 @@ enum TabType { Credits, Donate } }); onTabTypeChanged(TabType.Credits); + DonatorList.Instance.tryRequest(); + MinecraftForge.EVENT_BUS.register(this); + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + MinecraftForge.EVENT_BUS.unregister(this); } private void initTexts() { @@ -276,7 +288,8 @@ private void initTexts() { y += 1.5f * FontSize; - List donators = root.getStringList("donators"); + List donators = DonatorList.Instance.isLoaded() ? + DonatorList.Instance.getList() : root.getStringList("donators"); Collections.shuffle(donators); // Randomize the list for (int i = 0; i < donators.size(); ++i) { float tw = 150, margin = 30; @@ -348,6 +361,11 @@ public void handleMouseInput() throws IOException { } } + @SubscribeEvent + public void onDonatorListRefresh(DonatorListRefreshEvent e) { + initTexts(); + } + private void onTabTypeChanged(TabType type) { _tabType = type; setTabButtonEnable(_btnCredits, _tabType == TabType.Credits); diff --git a/src/main/resources/assets/academy/config/about.conf b/src/main/resources/assets/academy/config/about.conf index ace1fcbb2..3951c77ae 100644 --- a/src/main/resources/assets/academy/config/about.conf +++ b/src/main/resources/assets/academy/config/about.conf @@ -54,6 +54,7 @@ credits { "berry64", ] ] + // ! This list is not being maintained anymore and only serves as a fallback. donators: [ // patreon "anon katon", diff --git a/src/main/resources/assets/academy/lang/en_us.lang b/src/main/resources/assets/academy/lang/en_us.lang index 37bdb9ebf..ac2b44cf9 100644 --- a/src/main/resources/assets/academy/lang/en_us.lang +++ b/src/main/resources/assets/academy/lang/en_us.lang @@ -497,4 +497,4 @@ ac.converter.desc_template=Converts %s to %s ac.skill_tree.dev_developing=Developing... # About App -ac.about.donators_info=In no particular order\nThe list will be updated once a version +ac.about.donators_info=In no particular order diff --git a/src/main/resources/assets/academy/lang/zh_cn.lang b/src/main/resources/assets/academy/lang/zh_cn.lang index ca8cd8f54..7895f7af6 100644 --- a/src/main/resources/assets/academy/lang/zh_cn.lang +++ b/src/main/resources/assets/academy/lang/zh_cn.lang @@ -496,4 +496,4 @@ ac.headsOrTails.1=硬币反面朝上 ac.converter.desc_template=转换%s到%s # About App -ac.about.donators_info=排名不分先后\n名单每个版本更新一次 \ No newline at end of file +ac.about.donators_info=排名不分先后 \ No newline at end of file diff --git a/src/main/resources/assets/academy/lang/zh_tw.lang b/src/main/resources/assets/academy/lang/zh_tw.lang index 487488698..8a34c3f61 100644 --- a/src/main/resources/assets/academy/lang/zh_tw.lang +++ b/src/main/resources/assets/academy/lang/zh_tw.lang @@ -496,4 +496,4 @@ ac.converter.desc_template=轉換%s到%s # About App ac.app.about.name=關於 -ac.about.donators_info=排名不分先後\n名單每個版本更新壹次 +ac.about.donators_info=排名不分先後 diff --git a/src/test/java/DonatorListTest.kt b/src/test/java/DonatorListTest.kt new file mode 100644 index 000000000..33982d9f5 --- /dev/null +++ b/src/test/java/DonatorListTest.kt @@ -0,0 +1,12 @@ +import java.net.URL + +// Tests donation interface. +fun main(args: Array) { + val url = "http://144.34.208.247:8080/lambda/donation/sponsor" + val con = URL(url).openConnection() + con.doInput = true + + val wr = con.getInputStream() + val text = wr.bufferedReader().readText() + println(text) +} \ No newline at end of file From b6fe988746c92ddbdca3a5f8cc447413b730b547 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Mon, 18 Mar 2019 11:02:56 +0800 Subject: [PATCH 05/16] rename package analyticUtil -> analytic --- src/main/java/cn/academy/AcademyCraft.java | 2 +- .../java/cn/academy/ability/context/ContextManager.java | 2 +- .../{analyticUtil => analytic}/AnalyticDataListener.java | 6 +++--- .../cn/academy/{analyticUtil => analytic}/AnalyticDto.java | 2 +- .../{analyticUtil => analytic}/AnalyticInfoSender.java | 2 +- .../events/AnalyticLevelUpEvent.java | 2 +- .../events/AnalyticSkillEvent.java | 2 +- src/main/java/cn/academy/datapart/AbilityData.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) rename src/main/java/cn/academy/{analyticUtil => analytic}/AnalyticDataListener.java (98%) rename src/main/java/cn/academy/{analyticUtil => analytic}/AnalyticDto.java (98%) rename src/main/java/cn/academy/{analyticUtil => analytic}/AnalyticInfoSender.java (98%) rename src/main/java/cn/academy/{analyticUtil => analytic}/events/AnalyticLevelUpEvent.java (92%) rename src/main/java/cn/academy/{analyticUtil => analytic}/events/AnalyticSkillEvent.java (94%) diff --git a/src/main/java/cn/academy/AcademyCraft.java b/src/main/java/cn/academy/AcademyCraft.java index 0309d968f..060582792 100644 --- a/src/main/java/cn/academy/AcademyCraft.java +++ b/src/main/java/cn/academy/AcademyCraft.java @@ -1,6 +1,6 @@ package cn.academy; -import cn.academy.analyticUtil.AnalyticDataListener; +import cn.academy.analytic.AnalyticDataListener; import cn.lambdalib2.crafting.CustomMappingHelper; import cn.lambdalib2.crafting.RecipeRegistry; import cn.lambdalib2.registry.RegistryMod; diff --git a/src/main/java/cn/academy/ability/context/ContextManager.java b/src/main/java/cn/academy/ability/context/ContextManager.java index f7590c59d..5c00e7027 100644 --- a/src/main/java/cn/academy/ability/context/ContextManager.java +++ b/src/main/java/cn/academy/ability/context/ContextManager.java @@ -2,7 +2,7 @@ import cn.academy.AcademyCraft; import cn.academy.ability.context.Context.Status; -import cn.academy.analyticUtil.events.AnalyticSkillEvent; +import cn.academy.analytic.events.AnalyticSkillEvent; import cn.academy.event.ability.CategoryChangeEvent; import cn.academy.event.ability.OverloadEvent; import cn.lambdalib2.s11n.network.NetworkMessage; diff --git a/src/main/java/cn/academy/analyticUtil/AnalyticDataListener.java b/src/main/java/cn/academy/analytic/AnalyticDataListener.java similarity index 98% rename from src/main/java/cn/academy/analyticUtil/AnalyticDataListener.java rename to src/main/java/cn/academy/analytic/AnalyticDataListener.java index 5b87c7f3d..a03591663 100644 --- a/src/main/java/cn/academy/analyticUtil/AnalyticDataListener.java +++ b/src/main/java/cn/academy/analytic/AnalyticDataListener.java @@ -1,8 +1,8 @@ -package cn.academy.analyticUtil; +package cn.academy.analytic; import cn.academy.AcademyCraft; -import cn.academy.analyticUtil.events.AnalyticLevelUpEvent; -import cn.academy.analyticUtil.events.AnalyticSkillEvent; +import cn.academy.analytic.events.AnalyticLevelUpEvent; +import cn.academy.analytic.events.AnalyticSkillEvent; import cn.academy.datapart.AbilityData; import cn.academy.event.ability.LevelChangeEvent; import cn.academy.event.ability.SkillLearnEvent; diff --git a/src/main/java/cn/academy/analyticUtil/AnalyticDto.java b/src/main/java/cn/academy/analytic/AnalyticDto.java similarity index 98% rename from src/main/java/cn/academy/analyticUtil/AnalyticDto.java rename to src/main/java/cn/academy/analytic/AnalyticDto.java index 128849b70..c806740a4 100644 --- a/src/main/java/cn/academy/analyticUtil/AnalyticDto.java +++ b/src/main/java/cn/academy/analytic/AnalyticDto.java @@ -1,4 +1,4 @@ -package cn.academy.analyticUtil; +package cn.academy.analytic; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/cn/academy/analyticUtil/AnalyticInfoSender.java b/src/main/java/cn/academy/analytic/AnalyticInfoSender.java similarity index 98% rename from src/main/java/cn/academy/analyticUtil/AnalyticInfoSender.java rename to src/main/java/cn/academy/analytic/AnalyticInfoSender.java index 8d57b36a7..b594a54b7 100644 --- a/src/main/java/cn/academy/analyticUtil/AnalyticInfoSender.java +++ b/src/main/java/cn/academy/analytic/AnalyticInfoSender.java @@ -1,4 +1,4 @@ -package cn.academy.analyticUtil; +package cn.academy.analytic; import cn.academy.AcademyCraft; import com.google.gson.Gson; diff --git a/src/main/java/cn/academy/analyticUtil/events/AnalyticLevelUpEvent.java b/src/main/java/cn/academy/analytic/events/AnalyticLevelUpEvent.java similarity index 92% rename from src/main/java/cn/academy/analyticUtil/events/AnalyticLevelUpEvent.java rename to src/main/java/cn/academy/analytic/events/AnalyticLevelUpEvent.java index edd7a4177..7b32d5b7c 100644 --- a/src/main/java/cn/academy/analyticUtil/events/AnalyticLevelUpEvent.java +++ b/src/main/java/cn/academy/analytic/events/AnalyticLevelUpEvent.java @@ -1,4 +1,4 @@ -package cn.academy.analyticUtil.events; +package cn.academy.analytic.events; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.fml.common.eventhandler.Event; diff --git a/src/main/java/cn/academy/analyticUtil/events/AnalyticSkillEvent.java b/src/main/java/cn/academy/analytic/events/AnalyticSkillEvent.java similarity index 94% rename from src/main/java/cn/academy/analyticUtil/events/AnalyticSkillEvent.java rename to src/main/java/cn/academy/analytic/events/AnalyticSkillEvent.java index c50efa73e..b67e1f350 100644 --- a/src/main/java/cn/academy/analyticUtil/events/AnalyticSkillEvent.java +++ b/src/main/java/cn/academy/analytic/events/AnalyticSkillEvent.java @@ -1,4 +1,4 @@ -package cn.academy.analyticUtil.events; +package cn.academy.analytic.events; import cn.academy.ability.Skill; import net.minecraft.entity.player.EntityPlayer; diff --git a/src/main/java/cn/academy/datapart/AbilityData.java b/src/main/java/cn/academy/datapart/AbilityData.java index 87a1b713e..9603c24dd 100644 --- a/src/main/java/cn/academy/datapart/AbilityData.java +++ b/src/main/java/cn/academy/datapart/AbilityData.java @@ -4,7 +4,7 @@ import cn.academy.ability.Category; import cn.academy.ability.CategoryManager; import cn.academy.ability.Skill; -import cn.academy.analyticUtil.events.AnalyticLevelUpEvent; +import cn.academy.analytic.events.AnalyticLevelUpEvent; import cn.academy.event.ability.*; import cn.lambdalib2.datapart.DataPart; import cn.lambdalib2.datapart.EntityData; From a6090c4f758ae69a07e7ea12165805cf5bc8d1cc Mon Sep 17 00:00:00 2001 From: voidcl Date: Fri, 29 Mar 2019 17:35:46 +0800 Subject: [PATCH 06/16] move the analytic network module into a new thread . close #767 --- .../analytic/AnalyticDataListener.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/cn/academy/analytic/AnalyticDataListener.java b/src/main/java/cn/academy/analytic/AnalyticDataListener.java index a03591663..56f1dfb01 100644 --- a/src/main/java/cn/academy/analytic/AnalyticDataListener.java +++ b/src/main/java/cn/academy/analytic/AnalyticDataListener.java @@ -50,7 +50,11 @@ private AnalyticDataListener(){ @SubscribeEvent public void loginListener(PlayerEvent.PlayerLoggedInEvent event){ - String serverIp = getCurrentIPinfo(); + Thread delaySender = new DelaySender(event.player); + delaySender.start();//avoid sending message to the client thread before it hasn't been initialized + } + + public void serverGetter(EntityPlayer player,String serverIp){ if(null==serverSource) { serverSource = new AnalyticDto(); serverSource.setVersion(AcademyCraft.VERSION); @@ -66,12 +70,6 @@ public void loginListener(PlayerEvent.PlayerLoggedInEvent event){ serverSource.setCity(ipArray[5]); } } - Thread delaySender = new DelaySender(event.player,serverIp); - delaySender.start();//avoid sending message to the client thread before it hasn't been initialized - } - - @NetworkMessage.Listener(channel = "delay",side = Side.SERVER) - public void serverGetter(EntityPlayer player,String serverIp){ NetworkMessage.sendTo(player,this,CHANNEL,player,serverIp); } @@ -165,7 +163,7 @@ public void skillLearnListener(SkillLearnEvent event){ } //get ip info - private String getCurrentIPinfo(){ + public String getCurrentIPinfo(){ String ipInfo = ""; try { URL object = new URL("https://myip.ipip.net"); @@ -225,7 +223,7 @@ private long UTCZeroTime(){ class DelaySender extends Thread{ private EntityPlayer player; private String serverIp; - DelaySender(EntityPlayer player,String serverIp){ + DelaySender(EntityPlayer player){ this.player=player; this.serverIp=serverIp; } @@ -233,8 +231,8 @@ class DelaySender extends Thread{ public void run() { try { Thread.sleep(10000); - NetworkS11n.addDirectInstance(AcademyCraft.analyticDataListener); - NetworkMessage.sendToServer(AcademyCraft.analyticDataListener,"delay",player,serverIp); + serverIp = AcademyCraft.analyticDataListener.getCurrentIPinfo(); + AcademyCraft.analyticDataListener.serverGetter(player,serverIp); }catch (Exception e){ e.printStackTrace(); } From d7366cfa023bba57c794775ba0bdbfa998680b6f Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Thu, 11 Apr 2019 19:46:53 +0800 Subject: [PATCH 07/16] Add russian localization by dtraitor --- .../assets/academy/config/about.conf | 5 +- .../resources/assets/academy/lang/ru_ru.lang | 498 ++++++++++++++++++ 2 files changed, 501 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/assets/academy/lang/ru_ru.lang diff --git a/src/main/resources/assets/academy/config/about.conf b/src/main/resources/assets/academy/config/about.conf index 3951c77ae..c58ca5478 100644 --- a/src/main/resources/assets/academy/config/about.conf +++ b/src/main/resources/assets/academy/config/about.conf @@ -43,8 +43,9 @@ credits { ], [ "Localization", - "mkpoli", - "柳荫理乃" + "mkpoli (Japanese)", + "柳荫理乃 (Japanese)", + "dtraitor (Russian)" ], [ "GitHub Contributors", diff --git a/src/main/resources/assets/academy/lang/ru_ru.lang b/src/main/resources/assets/academy/lang/ru_ru.lang new file mode 100644 index 000000000..a55f37774 --- /dev/null +++ b/src/main/resources/assets/academy/lang/ru_ru.lang @@ -0,0 +1,498 @@ +# AcademyCraft Russian Language file +# This file is mainly categorized by use (except for those which needs to follow the rules of Minecraft). + +# Common +itemGroup.AcademyCraft=AcademyCraft +ac.data_config_parse_fail=[AcademyCraft] Failed to parse custom config data file. The error: + +# Item +item.ac_crystal_low.name=Кристалл низкой имаг частоты +item.ac_crystal_normal.name=Кристалл средней имаг частоты +item.ac_crystal_pure.name=Кристалл высокой имаг частоты +item.ac_constraint_ingot.name=Слиток ограниченого металла +item.ac_constraint_plate.name=Пластина ограниченого металла +item.ac_imag_silicon_ingot.name=Кремниевый имаг слиток +item.ac_wafer.name=Кремниевая имаг вафля +item.ac_imag_silicon_piece.name=Кусок имаг кремния +item.ac_reso_crystal.name=Резонирующий кристалл + +item.ac_brain_component.name=Анализатор мозговых волн +item.ac_info_component.name=Обработчик информации +item.ac_reinforced_iron_plate.name=Укрепленная железная пластина +item.ac_resonance_component.name=Резонатор +item.ac_energy_convert_component.name=Преобразователь энергии +item.ac_calc_chip.name=Вычислительный чип +item.ac_data_chip.name=Чип данных + +item.ac_matter_unit.name=Материальная единица +item.ac_matter_unit_phase_liquid.name=Жидкая имаг материальная единица +item.ac_matter_unit_none.name=Пустая единица +item.ac_matrix_core.name=Матричное ядро +item.ac_mat_core_0.name=Базовоя матричное ядро +item.ac_mat_core_1.name=Улучшеное матричное ядро +item.ac_mat_core_2.name=Продвинутое матричное ядро +item.ac_energy_unit.name=Энергетическая кдиницв +item.ac_windgen_fan.name=Ротор ветрогенератора + +item.ac_coin.name=Монета +item.ac_silbarn.name=Что-то кремниевое +item.ac_needle.name=Игла +item.ac_mag_hook.name=Магнитный крюк + +item.ac_terminal_installer.name=Терминал данных +item.ac_apps.name=Установщик приложений + +item.ac_developer_portable.name=Портативный производитель +item.ac_magnetic_coil.name=Магнитная катушка высокого напряжения +item.ac_magnetic_coil.desc=Заряжает разработчика
Для того, чтобы переписать личную реальность +item.ac_induction_factor.name=Коэфициент индукционной способности +item.ac_tutorial.name=Терминал MisakaCloud + +# Block +tile.ac_constraint_metal.name=Ограниченая металлическая руда +tile.ac_crystal_ore.name=Имаг кристалическая руда +tile.ac_imagsil_ore.name=Имаг кремниевая руда +tile.ac_reso_ore.name=Резонирующая кристальная руда +tile.ac_machine_frame.name=Машинный корпус + +tile.ac_imag_phase.name=Переходник в имаг жидкость + +tile.ac_imag_fusor.name=Имаг Термоблок +tile.ac_matrix.name=Беспроводная Имаг Матрица +tile.ac_node_basic.name=Базовая беспроводная имаг нода +tile.ac_node_standard.name=Улучшеная беспроводная имаг нода +tile.ac_node_advanced.name=Продвинутая беспроводная имаг нода +tile.ac_metal_former.name=Металло формировщик +tile.ac_solar_gen.name=Солнечный генератор +tile.ac_cat_engine.name=Кот и Тост +tile.ac_phase_gen.name=Фазовый генератор +tile.ac_windgen_base.name=Основа столба ветрогенератора +tile.ac_windgen_pillar.name=Столб ветрогенератора +tile.ac_windgen_main.name=Ветрогенератор +tile.ac_eu_output.name=Енергентический мост (IC2 EU Выходит) +tile.ac_eu_input.name=Енергентический мост (IC2 EU Входит) +tile.ac_rf_output.name=Енергентический мост (CoFH RF Выходит) +tile.ac_rf_input.name=Енергентический мост (CoFH RF Входит) +tile.ac_dev_normal.name=Разработчик нормальных способностей +tile.ac_dev_advanced.name=Разработчик продвинутых способностей +tile.ac_ability_interferer.name=Умение мешать (я сам хз) + +# Data Terminal +ac.terminal.notinstalled=Вы еще не установили Терминал Данных. +ac.terminal.alrdy_installed=Вы уже установили Терминал Данных. +ac.terminal.key_hint=Терминал Данных успешно установлен. Используйте кнопку %s что-бы открыть/закрыть интерфейс +ac.gui.terminal.installing= Установка... +ac.gui.terminal.appcount=%d Приложений + +ac.terminal.app_alrdy_installed=Вы уже установили приложение %s. +ac.terminal.app_installed=Вы успешно установили приложение %s. + +# Apps +ac.app.skill_tree.name=Древо Умений +ac.app.knowledge_record.name=Записыватель жизни +ac.app.settings.name=Настройки +ac.app.media_player.name=Медиа проигрыватель +ac.app.tutorial.name=MisakaCloud +ac.app.about.name=Информация + +ac.app.freq_transmitter.name=Передатчик частот +ac.app.freq_transmitter.s0_0=Пожалуйста, щелкните правой кнопкой мыши на беспроводной матрице или узле, чтобы начать устанавливать связь с. +ac.app.freq_transmitter.s1_0=Нажмите ENTER что-бы продолжить +ac.app.freq_transmitter.s1_1=Авторизация... +ac.app.freq_transmitter.s2_0=Щелкните правой кнопкой мыши на любом беспроводном узле поблизости, чтобы установить связь. Нажмите на любые другие блоки, чтобы выйти. +ac.app.freq_transmitter.s3_0=Щелкните правой кнопкой мыши по любому беспроводному приемнику или генераторе поблизости, чтобы добавить ссылку. Нажмите на любые другие блоки, чтобы выйти. +ac.app.freq_transmitter.st=Время действия вышло. + +ac.app.freq_transmitter.e0=Беспроводная матрица не инициализирована. +ac.app.freq_transmitter.e1=Ошибка авторизации. +ac.app.freq_transmitter.e2=Соеденение прервано. Возможно, матрица достигла своей емкости или сигнал находится вне диапазона. +ac.app.freq_transmitter.e3=Соеденение прервано. Возможно, нода достигла своей емкости или сигнал находится вне диапазона. +ac.app.freq_transmitter.e4=Действие отменено. +ac.app.freq_transmitter.e5=Передача... +ac.app.freq_transmitter.e6=Соеденение успешно. + +## Settings App +ac.settings.cat.generic=Общие +ac.settings.prop.attackPlayer=Включить PvP +ac.settings.prop.destroyBlocks=Уничтожать блоки +ac.settings.prop.headsOrTails=Играть в головы или хвосты (Автор нарк) +ac.settings.prop.useMouseWheel=Колесо мыши регулирует расстояние телепортации +#Use mouse wheel to adjust Penetrate Teleport distance + +ac.settings.cat.keys=Клавиши +ac.settings.prop.ability_activation=Активировать способность +ac.settings.prop.edit_preset=Редактировать пресет +ac.settings.prop.switch_preset=Переключить пресет +ac.settings.prop.open_data_terminal=Открыть Терминал Данных +ac.settings.prop.ability_0=Способность #1 +ac.settings.prop.ability_1=Способность #2 +ac.settings.prop.ability_2=Способность #3 +ac.settings.prop.ability_3=Способность #4 +ac.settings.prop.debug_console=Дебаг Консоль + +ac.settings.cat.misc=Остальное +ac.settings.prop.edit_ui=Кастомизировать Интерфейс + +## Media App +## -> ac.app.media.* +ac.media.acquired=Вы установили медиа-файл %s +ac.media.haveone=Вы уже установили медиа-файл %s +ac.media.notinstalled=Вы еще не установили Медиа Проигрователь. + +### Medias +ac.media.only_my_railgun.name=only my railgun +ac.media.only_my_railgun.desc=Toaru Kagaku no Railgun OP1 +ac.media.level5_judgelight.name=LEVEL5-judgelight- +ac.media.level5_judgelight.desc=Toaru Kagaku no Railgun OP2 +ac.media.sisters_noise.name=sister's noise +ac.media.sisters_noise.desc=Toaru Kagaku no Railgun S OP1 + +# Ability Generic +ac.ability.level0=Уровень 0 +ac.ability.level1=Уровень 1 +ac.ability.level2=Уровень 2 +ac.ability.level3=Уровень 3 +ac.ability.level4=Уровень 4 +ac.ability.level5=Уровень 5 + +death.attack.ac_skill=%1$s был убит %2$s припомощи %3$s + +ac.activate_key.deactivate.desc=Деактивировать способность +ac.activate_key.endspecial.desc=Завершить режим специальных навыков +ac.activate_key.endskill.desc=Откатить умение + +ac.gui.preset_edit.name=Редактировать премет +ac.gui.preset_edit.tag=Пресет # +ac.gui.preset_edit.skill_remove=Удалить текущий +ac.gui.preset_edit.skill_select=Выбрать умение + +## Generic Skills +ac.ability.generic.brain_course.name=Мозговой курс +ac.ability.generic.brain_course_advanced.name=Продвинутый курс мозга +ac.ability.generic.mind_course.name=Курс разума (Внимания, может духа) +ac.ability.generic.brain_course.desc=Uпройти тренировку для вашего мозга. Увеличивает Макс. CP на 1000. +ac.ability.generic.brain_course_advanced.desc=Развивть мыслительные способности вашего мозга глубже. Увеличивает Макс. CP на 1000 и Макс. Перегрузку на 100. +ac.ability.generic.mind_course.desc=Узнайте, как лучше расслабить свой мозг. Ускоряет восстановление CP на 20 %%. + +## Electromaster +ac.ability.electromaster.name=Электромастер + +### EM Skills +ac.ability.electromaster.arc_gen.name=Генерация дуги +ac.ability.electromaster.mag_manip.name=Магнитные манипуляции +ac.ability.electromaster.mine_detect.name=Обнаружение мин +ac.ability.electromaster.railgun.name=Рейлган +ac.ability.electromaster.mag_movement.name=Магнитное движение +ac.ability.electromaster.iron_sand.name=Контрль железного песка +ac.ability.electromaster.iron_sand.sword.name=Меч из железного песка +ac.ability.electromaster.iron_sand.whip.name=Кнут из железного песка +ac.ability.electromaster.iron_sand.storm.name=Буря из железного песка +ac.ability.electromaster.iron_sand.cone.name=Конус из железного песка +ac.ability.electromaster.charging.name=Текущая зарядка +ac.ability.electromaster.body_intensify.name=Активизировать тело +ac.ability.electromaster.thunder_clap.name=Удар грома +ac.ability.electromaster.thunder_bolt.name=Молния + +ac.ability.electromaster.arc_gen.desc=Вызывает слабую электрическую дугу, которая наносит небольшой урон по области, которую она поражает. Если он непосредственно попадет на огнеопасный блок, у него будет шанс его зажечь. +ac.ability.electromaster.mag_manip.desc=Управляйте и перемещайте намагничиваемые предметы с помощью магнитной силы, даже выбрасывайте их, чтобы повредить врагов. +ac.ability.electromaster.mine_detect.desc=Закройте глаза и почувствуйте поток магнетизма, позволяющий увидеть намеки на драгоценные минеральные ресурсы вокруг вас. +ac.ability.electromaster.railgun.desc=Стреляйте монетой на высокой скорости с помощью электромагнитной индукции. Причиняет разрушительный ущерб там, где она воздействует. +ac.ability.electromaster.mag_movement.desc=Создайте сильное магнитное поле и притяните себя к какой-нибудь магнитной цели. Чрезвычайно полезен при движении или побеге. +ac.ability.electromaster.iron_sand.desc=Отделите железо от песка и управляйте им, чтобы создать изменчивый и опасный эффект атаки. +ac.ability.electromaster.charging.desc=Генерирует электрический ток для зарядки вещи в вашей руке или электрических блоков в мире. +ac.ability.electromaster.body_intensify.desc=Точно настройте биоэлектричество, чтобы улучшить свои физические способности на короткое время. +ac.ability.electromaster.thunder_clap.desc=Управляйте магнитным полем в атмосфере, создавая грозовые тучи, и направляйте электричество вниз, чтобы вызвать разрушительный удар молнии. +ac.ability.electromaster.thunder_bolt.desc=Сжимает огромное количество электричества в мощный болт, взрываясь и повреждая что-либо в его области. + +## Teleporter +ac.ability.teleporter.name=Телепортер + +### TP Skills +ac.ability.teleporter.threatening_teleport.name=Угрожающий Телепорт +ac.ability.teleporter.dim_folding_theorem.name=Размерная теорема складывания +ac.ability.teleporter.penetrate_teleport.name=Проникающий телепорт +ac.ability.teleporter.mark_teleport.name=Телепортация по метке +ac.ability.teleporter.flesh_ripping.name=Разрывание плоти +ac.ability.teleporter.location_teleport.name=Телепорт по локации +ac.ability.teleporter.shift_tp.name=Телепортационный сдвиг +ac.ability.teleporter.space_fluct.name=Колебания пространства +ac.ability.teleporter.flashing.name=Мигание + +ac.ability.teleporter.threatening_teleport.desc=Телепортируйте предметы куда-то вокруг вас. Иногда даже маленький фрагмент способен убить врага. +ac.ability.teleporter.dim_folding_theorem.desc=Увеличьте свой урон против врагов, создавая крошечный феномен складывания пространства. +ac.ability.teleporter.penetrate_teleport.desc=Определите толщину препятствия перед вами и телепортируйтесь прямо через него. +ac.ability.teleporter.mark_teleport.desc=Отмечает, куда вы смотрите как пункт назначения, и телепортирует вас туда. +ac.ability.teleporter.flesh_ripping.desc=Разорвите внутри вашего врага и нанесите кровавый урон. Чрезмерно кровавый эффект может вызвать у вас дискомфорт. +ac.ability.teleporter.location_teleport.desc=Запомните ваше текущее местоположение и телепортируйтесь обратно из любого места, которое будет дальше. +ac.ability.teleporter.shift_tp.desc=Телепортируйте блок по кординатной прямой. На пуьи блок повредит сущность +ac.ability.teleporter.space_fluct.desc=Усильте свою способность складывать пространство, чтобы наносить более опасный критический урон. +ac.ability.teleporter.flashing.desc=Используйте несколько телепортаций за короткое время, чтобы маневрировать по воздуху. +ac.ability.teleporter.crithit=%fx критический удар! + +ac.gui.loctele.err_exp=Слишком мало опыта, немогу пройти измерение +ac.gui.loctele.err_cp=CP недостаточно, немогу телепортироватся + +## Meltdowner +ac.ability.meltdowner.name=Плавитель + +### MD Skills +ac.ability.meltdowner.electron_bomb.name=Бомьа из электронов +ac.ability.meltdowner.rad_intensify.name=β Радиационная интенсивность +ac.ability.meltdowner.ray_barrage.name=Спектр лучей +ac.ability.meltdowner.scatter_bomb.name=Касетные бомбы +ac.ability.meltdowner.meltdowner.name=Плавитель +ac.ability.meltdowner.light_shield.name=Молниеносный щит +ac.ability.meltdowner.jet_engine.name=Реактивный двигатель +ac.ability.meltdowner.mine_ray_basic.name=Базовый копательный луч +ac.ability.meltdowner.mine_ray_expert.name=Экспертный копательный луч +ac.ability.meltdowner.mine_ray_luck.name=Везучий копательный луч +ac.ability.meltdowner.electron_missile.name=Заряд электронов + +ac.ability.meltdowner.electron_bomb.desc=Соберите небольшое количество электронов, чтобы создать угрожающий луч. +ac.ability.meltdowner.rad_intensify.desc=Из-за излучения высокой интенсивности цель, пораженная лучом, вдвойне уязвима для атак в течение нескольких секунд.. +ac.ability.meltdowner.ray_barrage.desc=SВыстрелите своим высокоэнергетическим лучом в Силиконовый сарай (сам хз), чтобы рассеять его в лучевой барьер, который разрушает все перед вами. +ac.ability.meltdowner.scatter_bomb.desc=Манипулируйте более чем одной групой электронов для атаки. В результате вы не можете точно контролировать точку удара. +ac.ability.meltdowner.meltdowner.desc=Экстремальный высокоэнергетический электронный пучок, который расплавляет стены и металлы. +ac.ability.meltdowner.light_shield.desc=Формирует электроны в щит. Быстро движущиеся электроны уничтожат все, что вас атакует, и повредят все, что вас коснется. +ac.ability.meltdowner.jet_engine.desc=Используйте движущую силу электронов, запускайте себя в воздух. Создаст легкий щит, чтобы защитить вас в полете. +ac.ability.meltdowner.mine_ray_basic.desc=После долгой практики вы можете сделать свой электронный луч пригодным для сбора полезных ископаемых, не разрушая их. +ac.ability.meltdowner.mine_ray_expert.desc=Понимая, как лучше контролировать интенсивность электронов, теперь вы можете более эффективно собирать минеральные ресурсы. +ac.ability.meltdowner.mine_ray_luck.desc=После долгой практики вы можете практически полностью собрать полезные ресурсы в руде.. +ac.ability.meltdowner.electron_missile.desc=Соберите ОГРОМНОЕ количество электронов в облаке и используйте некоторые из них для атаки каждый раз. + +## Vector Manipulation +ac.ability.vecmanip.name=Векторные манипуляции + +### VM skills +ac.ability.vecmanip.dir_shock.name=Направленый шок +ac.ability.vecmanip.ground_shock.name=Шок по земле +ac.ability.vecmanip.vec_accel.name=Векторная прокрутка +ac.ability.vecmanip.vec_deviation.name=Вектор отклонение +ac.ability.vecmanip.dir_blast.name=Направленная взрывная волна +ac.ability.vecmanip.storm_wing.name=Крылья шторма +ac.ability.vecmanip.blood_retro.name=Кровавый град +ac.ability.vecmanip.vec_reflection.name=Векторная реакция +ac.ability.vecmanip.plasma_cannon.name=Плазменная пушка + +ac.ability.vecmanip.dir_shock.desc=Захватите противодействующую силу при ударе по объекту и перенаправьте его на сам объект, делая удар более мощным. +ac.ability.vecmanip.ground_shock.desc=Нанесите мощный удар по земле и направьте его вперед, который разбивает землю и запускает врагов в воздух. +ac.ability.vecmanip.vec_accel.desc=Увеличьте силу прыжка на мгновение, чтобы ускорить себя. +ac.ability.vecmanip.vec_deviation.desc=Отменяет скорость снарядов, летящих к вам, и отменяет часть боевого урона. +ac.ability.vecmanip.dir_blast.desc=Утройте силу удара в объект, делая его чрезвычайно разрушительным. Будет разбивать блоки на области, которую он поражает. +ac.ability.vecmanip.storm_wing.desc=Управляйте скоростью воздуха, чтобы сформировать четыре микро-вихря на вашей спине, и летите на высокой скорости, используя силы, которые они генерируют. Будут разбивать блоки поблизости, если неопытный. +ac.ability.vecmanip.blood_retro.desc=Размешайте кровоток органических врагов, чтобы их сосуд лопнул и умер от сильной боли. +ac.ability.vecmanip.vec_reflection.desc=Отражает опасные входящие атаки в направлении вашей прямой видимости и заставляет вашего противника выдержать это. +ac.ability.vecmanip.plasma_cannon.desc=Управляйте большой областью воздушного потока с чрезвычайной точностью, чтобы сформировать плазменное тело. Выбросьте его, чтобы вызвать катастрофический взрыв. + +# Command +ac.command.invalid=§cInvalid input, please try again. +ac.command.successful=§2Command sucessfully performed. +ac.command.notlearned=§6The player has not learned any ability yet. + +ac.command.knowledge.usage=/knowledge | [parameters...] +ac.command.knowledge.help=/knowledge help: Display the help message. +ac.command.knowledge.stat=/knowledge stat: Show statistics info of player ac.knowledge. +ac.command.knowledge.clear=/knowledge clear: Clear all knowledge info and start over again. +ac.command.knowledge.getall=/knowledge getall: Learn all knowledges right now. +ac.command.knowledge.list=/knowledge list: List all available knowledges. +ac.command.knowledge.learn=/knowledge learn [knowledge_name]: Learn some ac.knowledge. +ac.command.knowledge.unlearn=/knowledge unlearn [knowledge_name]: Unlearn some ac.knowledge. +ac.command.knowledge.stat2=Knowledge learned: %s +ac.command.knowledge.stat3=Knowledge discovered: %s +ac.command.knowledge.notfound=Knowledge with name %s doesn't exist. +ac.command.knowledge.all=All knowledges: +ac.command.knowledge.discover=/knowledge discover [knowledge_name]: Discover a specific ac.knowledge. + +ac.command.aim.usage=/aim | [parameters...] +ac.command.aim.help=/aim help: Display the help message. +ac.command.aim.cat=/aim cat [catName]: Change the specified player's categories or display the current category. +ac.command.aim.catlist=/aim catlist: List all available categories' names. +ac.command.aim.learn=/aim learn |: Learn the specified skill, regardless of its learning condition requirements. +ac.command.aim.unlearn=/aim unlearn |: Unlearn the specified skill. +ac.command.aim.learn_all=/aim learn_all: Learn all the skills. +ac.command.aim.reset=/aim reset: Clear your ability information. +ac.command.aim.learned=/aim learned: Display all currently learned skills. +ac.command.aim.skills=/aim skills: Display all skills in player's current category. +ac.command.aim.fullcp=/aim fullcp: Restore full cp of the player. +ac.command.aim.level=/aim level: Set the player's ability level. +ac.command.aim.exp=/aim exp | [exp]: Set or view the skill's experience level. +ac.command.aim.cd_clear=/aim cd_clear: Clear all skill cooldown. +ac.command.aim.nocat=Specified category not found. Use /aim catlist to list all categories. +ac.command.aim.cats=Currently available categories: +ac.command.aim.curcat=Player current category: %s +ac.command.aim.nonecat=No ability +ac.command.aim.noskill=No such skill was found. Use /aim skills to list all skills in current category. +ac.command.aim.learned.format=Learned skills: %s +ac.command.aim.curexp=Skill %s's current exp: %.0f%%. +ac.command.aim.notactive=The /aim command is currently inactive. Use /aim cheats_on or /aim cheats_off to change the active state. +ac.command.aim.warning=§cWARNING: Using /aim command will break the game balance and impact your experience about the mod, PROCEED WITH CAUTION! +ac.command.aim.outofrange=§cInput out of range: §fMust be a value between %s and %s. +ac.command.aim.invalidnum=§cInvalid number: %s. +ac.command.aim.maxout=Set current level's upgrade progress to 100%%. +ac.command.aim.nocomm=No such command was found. Use /aim help to list all commands available. +ac.command.aim.nonecathint=Ты еще не выучил никакой способности! + +ac.command.aimp.usage=/aimp | [parameters...] +ac.command.aimp.help=/aimp help: Display the help message. +ac.command.aimp.cat=/aimp cat [catName]: Change the specified player's categories or display the current category. +ac.command.aimp.catlist=/aimp catlist: List all available categories' names. +ac.command.aimp.learn=/aimp learn |: Learn the specified skill, regardless of its learning condition requirements. +ac.command.aimp.unlearn=/aimp unlearn |: Unlearn the specified skill. +ac.command.aimp.learn_all=/aimp learn_all: Learn all the skills. +ac.command.aimp.reset=/aimp reset: Clear your ability information. +ac.command.aimp.learned=/aimp learned: Display all currently learned skills. +ac.command.aimp.skills=/aimp skills: Display all skills in player's current category. +ac.command.aimp.fullcp=/aimp fullcp: Restore full cp of the player. +ac.command.aimp.level=/aimp level: Set the player's ability level. +ac.command.aimp.exp=/aimp exp | [exp]: Set or view the skill's experience level. +ac.command.aimp.cd_clear=/aimp cd_clear: Clear all skill cooldown. +ac.command.aimp.nocat=Specified category not found. Use /aimp catlist to list all categories. +ac.command.aimp.cats=Возможные сейчас категории: +ac.command.aimp.curcat=Категория игрока: %s +ac.command.aimp.nonecat=Нет способности +ac.command.aimp.noskill=No such skill was found. Use /aimp skills to list all skills in current category. +ac.command.aimp.learned.format=Выучено умение: %s +ac.command.aimp.curexp=Skill %s's опыта сейчас: %.0f%%. +ac.command.aimp.notactive=The /aimp command is currently inactive. Use /aimp cheats_on or /aimp cheats_off to change the active state. +ac.command.aimp.warning=§cWARNING: Using /aimp command will break the game balance and impact your experience about the mod, PROCEED WITH CAUTION! +ac.command.aimp.outofrange=§cЗа доступным радиусом: §fДолжно быть значение между %s и %s. +ac.command.aimp.maxout=/aimp maxout:Set current level's upgrade progress to 100%%. +ac.command.aimp.nocomm=No such command was found. Use /aimp help to list all commands available. +ac.command.aimp.nonecathint=Ты еще не выучил никакой способности! + +# Advancement +advancements.general.root=Academy Craft +advancements.general.root.desc=Начало всего +advancements.general.open_misaka_cloud=Первый контак +advancements.general.open_misaka_cloud.desc=Открыть Misaka Cloud +advancements.general.getting_phase=Мистический и мощный +advancements.general.getting_phase.desc=Получить капсулу с жидким Имагом +advancements.general.phase_generator=Новая энергия +advancements.general.phase_generator.desc=Сделать фазовый генератор +advancements.general.ac_node=Больше никаких проводов! +advancements.general.ac_node.desc=Сделать базовую беспроводную имаг ноду +advancements.general.ac_matrix=WIFI доступен тут +advancements.general.ac_matrix.desc=Сделать матрицу +advancements.general.terminal_installed=Технологии изменяют жизнь +advancements.general.terminal_installed.desc=Установить информационный терминал +advancements.general.getting_factor=Бесконечные возможности +advancements.general.getting_factor.desc=Получить фактор индукции +advancements.general.ac_developer=Лимит для людей +advancements.general.ac_developer.desc=Сделать портативный производчик способностей +advancements.general.dev_category=Над человеком +advancements.general.dev_category.desc=Сделать способнсть +advancements.general.ac_level_3=На своих двух +advancements.general.ac_level_3.desc=Улучшиться до 3 уровня +advancements.general.ac_level_5=Один в поле воин +advancements.general.ac_level_5.desc=Улучишться до 5 уровня +advancements.general.convert_category=Больше никаких случайностей +advancements.general.convert_category.desc=Изменить свою категорию +advancements.general.ac_learning_skill=Практика делает идеальным +advancements.general.ac_learning_skill.desc=Выучить любое умение +advancements.general.ac_milestone=Улучшить модуль +advancements.general.ac_milestone.desc=Достигните рубежа первого навыка +advancements.general.ac_exp_full=Сколько раз ты это сделал? +advancements.general.ac_exp_full.desc=Получи весь опыт на умении +advancements.general.ac_overload=Тут досих пор лимит на ESPов +advancements.general.ac_overload.desc=Используй свое умение пока оно не перегрузится + +# UI Commons +ac.gui.common.pg_wireless.not_connected=Не подключено +ac.gui.common.sep.info=Информация +ac.gui.common.sep.wireless_info=Беспроводная информация +ac.gui.common.sep.wireless_init=Инициализация беспроводной сети +ac.gui.common.sep.wireless_noinit=Беспроводная сеть не инициализирована +ac.gui.common.sep.change_pass=Измениит пароль +ac.gui.common.hist.energy=ЭНЕРГИЯ +ac.gui.common.hist.buffer=ЗАПАС +ac.gui.common.hist.liquid=ЖИДКОСТЬ +ac.gui.common.hist.capacity=ВМЕСТИМОСТЬ +ac.gui.common.prop.range=Длинна транспортировки +ac.gui.common.prop.owner=Владелец +ac.gui.common.prop.node_name=Имя ноды +ac.gui.common.prop.password=Пароль +ac.gui.common.prop.bandwidth=Пропускная способность +ac.gui.common.prop.ssid=SSID +ac.gui.common.prop.gen_speed=Скорость генерации +ac.gui.common.prop.altitude=Высота + +# Skill Tree +ac.skill_tree.dev_successful=Производство успешно. +ac.skill_tree.dev_failed=Производство провалено. +ac.skill_tree.progress=Прогрес... +ac.skill_tree.noenergy=Недостаточно энергии. +ac.skill_tree.condition_fail=Состояние развития не соблюдено. +ac.skill_tree.learn_question=Выучить? (Потребление Estm.:%s ЕСЛИ) +ac.skill_tree.level_question=Продолжить? +ac.skill_tree.req=Нужно. +ac.skill_tree.skill_not_learned=Умение не выучено. +ac.skill_tree.skill_exp=Опыт умения: +ac.skill_tree.uplevel=Улучшить до %s +ac.skill_tree.anyskill=Любое умение выучено до уровня: %d +ac.skill_tree.level_fail=Сначала вам надо получить %d уровень. + +ac.skill_tree.type_portable=Портативный производитель +ac.skill_tree.type_normal=Обычный производитель +ac.skill_tree.type_advanced=Продвинутый производитель + +ac.skill_tree.console.init=Добро пожаловать в Academy OS, Ver 1.0.1\nCopyright (c) Academy Tech. All rights reserved. \nПользователь %s обнаружен, Запуск системы...... +ac.skill_tree.console.invalid_cat=\nFATAL: Категория пользовательских возможностей неверна, запуск отменен.\n +ac.skill_tree.console.learn_hint=Наберите `learn` чтобы приобрести новую категорию.\n +ac.skill_tree.console.override=\nWARNING: Переопределение системы! Обнаруженое наружное вторжение.....\n\nСБРАСЫВАНИЕ СПОСОБНОСТЕЙ: Используйте команду `reset` чтобы сбросить китегорию. \nМинимальный уровень способностей:3, и индукционный фактор должен быть в инвентаре.\n +ac.skill_tree.console.boot_failed=Запуск провелен.\n +ac.skill_tree.console.invalid_command=Неверная команда.\n +ac.skill_tree.console.progress=Прогрес: %s%% +ac.skill_tree.console.reset_begin=Начат сброс категории... +ac.skill_tree.console.reset_succ=Успешный сброс личной реальности.\n +ac.skill_tree.console.reset_fail=Сброс личной реальности провален.\n +ac.skill_tree.console.reset_fail_dev=Неможу сбросить возможности -- Надо использувать продвинутый производитель.\n +ac.skill_tree.console.reset_fail_other=Неможем сбросить способности -- Уровень ниже 3, или индукционный фактор не обнаружен.\n +ac.skill_tree.console.dev_begin=начало симуляции......\n +ac.skill_tree.console.dev_succ=Производство успешно.\n +ac.skill_tree.console.dev_fail=Производство провалено.\n + +# Phase Generator + +# Imag Fusor + +# Metal Former +ac.gui.metal_former.mode.etch=Гравировка +ac.gui.metal_former.mode.plate=Дробление пластин +ac.gui.metal_former.mode.incise=Вырезка +ac.gui.metal_former.mode.refine=Очистка + +# Ability interference block +ac.gui.ability_interf.switch=Переключить +ac.ability_interf.cantuse=Вы не можете использовать этот блок помех. + +# UI Editing +ac.gui.uiedit.elements=Элементы + +ac.gui.uiedit.elm.cpbar=Индикатор CP +ac.gui.uiedit.elm.keyhint=Контроль подсказок +ac.gui.uiedit.elm.notification=Уведомления +ac.gui.uiedit.elm.media=Медиа проигрыватель + +# Cat Engine +ac.cat_engine.unlink=Отключен от ноды meow~ +ac.cat_engine.notfound=Поблизости не найдена нода meow~ +ac.cat_engine.linked=Подключен к ноду подназванием %s meow~ + +# Tutorials +ac.gui.crafttype.shaped=Shaped Crafting +ac.gui.crafttype.shapeless=Shapeless Crafting + +ac.tutorial.crafting=Crafting: %s +ac.tutorial.misaka=Misaka Не.%d +ac.tutorial.update=Cloud Terminal обновлен + +# Heads Or Tails +ac.headsOrTails.0=Результат ХВОСТЫ! +ac.headsOrTails.1=Результат ГОЛОВЫ! + +# Converter Block +ac.converter.desc_template=Конвертирует %s в %s +ac.skill_tree.dev_developing=Производим... + +# About App +ac.about.donators_info=In no particular order\nThe list will be updated once a version From cce0c004356bf0c341a6ad34e7017b58cfe22d67 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Thu, 11 Apr 2019 19:53:19 +0800 Subject: [PATCH 08/16] Minor fix --- src/main/java/cn/academy/terminal/DonatorList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/academy/terminal/DonatorList.java b/src/main/java/cn/academy/terminal/DonatorList.java index 4d639e1ba..ac28d4fb7 100644 --- a/src/main/java/cn/academy/terminal/DonatorList.java +++ b/src/main/java/cn/academy/terminal/DonatorList.java @@ -45,7 +45,7 @@ public void tryRequest() { _requesting = true; new Thread(() -> { try { - String url = "http://144.34.208.247:8080/lambda/donation/sponsor"; + String url = "https://ac.li-dev.cn/donators"; URLConnection con = new URL(url).openConnection(); con.setDoInput(true); From 63539e2a3a1e2c10ebd078e50d135ebb60248942 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Tue, 23 Apr 2019 22:16:53 +0800 Subject: [PATCH 09/16] StormWing: Use minecraft keybinding for movement. Close #712 --- .../ability/vanilla/teleporter/skill/Flashing.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/cn/academy/ability/vanilla/teleporter/skill/Flashing.java b/src/main/java/cn/academy/ability/vanilla/teleporter/skill/Flashing.java index 35fee346b..5368e2101 100644 --- a/src/main/java/cn/academy/ability/vanilla/teleporter/skill/Flashing.java +++ b/src/main/java/cn/academy/ability/vanilla/teleporter/skill/Flashing.java @@ -19,6 +19,8 @@ import cn.lambdalib2.util.Raytrace; import cn.lambdalib2.util.VecUtils; import com.google.common.base.Preconditions; +import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.GameSettings; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; @@ -28,7 +30,6 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import org.lwjgl.input.Keyboard; import java.util.Optional; @@ -136,7 +137,15 @@ void localMakeAlive() { clientRuntime().addActivateHandler(activateHandler); final String[] strs = new String[] { null, "a", "d", "w", "s"}; - final int[] keys = new int[] { -1, Keyboard.KEY_A, Keyboard.KEY_D, Keyboard.KEY_W, Keyboard.KEY_S }; + Minecraft mc = Minecraft.getMinecraft(); + GameSettings settings = mc.gameSettings; + final int[] keys = new int[] { + -1, + settings.keyBindLeft.getKeyCode(), + settings.keyBindRight.getKeyCode(), + settings.keyBindForward.getKeyCode(), + settings.keyBindBack.getKeyCode() + }; for (int i = 0; i < 4; ++i) { final int localid = i + 1; clientRuntime().addKey(KEY_GROUP, keys[localid], new KeyDelegate() { From 1896f268a86504454967d4c5db3aa9e4d6859468 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Tue, 23 Apr 2019 22:36:08 +0800 Subject: [PATCH 10/16] Fix infinite recursion for Vector Reflection. Close #759 --- .../vecmanip/skill/VecReflection.scala | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/VecReflection.scala b/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/VecReflection.scala index 1f6c8c906..dfc6192f1 100644 --- a/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/VecReflection.scala +++ b/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/VecReflection.scala @@ -29,7 +29,7 @@ object VecReflection extends Skill("vec_reflection", 4) { MinecraftForge.EVENT_BUS.register(this) @SideOnly(Side.CLIENT) - override def activate(rt: ClientRuntime, keyid: Int) = { + override def activate(rt: ClientRuntime, keyid: Int): Unit = { rt.addKey(keyid, KeyDelegates.contextActivate(this, new VecReflectionContext(_))) } @@ -63,19 +63,19 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { import scala.collection.JavaConversions._ @Listener(channel=MSG_MADEALIVE, side=Array(Side.SERVER)) - def s_makeAlive() = { + def s_makeAlive(): Unit = { MinecraftForge.EVENT_BUS.register(this) ctx.consume(overloadToKeep, 0) overloadKeep = ctx.cpData.getOverload } @Listener(channel=MSG_TERMINATED, side=Array(Side.SERVER, Side.CLIENT)) - def g_terminate() = { + def g_terminate(): Unit = { MinecraftForge.EVENT_BUS.unregister(this) } @Listener(channel=MSG_TICK, side=Array(Side.SERVER)) - def s_tick() = { + def s_tick(): Unit = { if(ctx.cpData.getOverload < overloadKeep) ctx.cpData.setOverload(overloadKeep) val range = 4 val entities = WorldUtils.getEntities(player, range, new Predicate[Entity] { @@ -111,10 +111,10 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { visited ++= entities if(!consumeNormal) - terminate + terminate() } - private def createNewFireball(source : EntityFireball) = { + private def createNewFireball(source : EntityFireball): Boolean = { source.setDead() val shootingEntity = source.shootingEntity @@ -146,13 +146,13 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { } @Listener(channel=MSG_TICK, side=Array(Side.CLIENT)) - def c_tick() = { + def c_tick(): Unit = { if(!consumeNormal) - terminate + terminate() } @SubscribeEvent - def onReflect(evt: ReflectEvent) = { + def onReflect(evt: ReflectEvent): Unit = { if (evt.target.equals(player)) { evt.setCanceled(true) @@ -166,7 +166,7 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { * to be one more pre testing. */ @SubscribeEvent - def onLivingAttack(evt: LivingAttackEvent) = { + def onLivingAttack(evt: LivingAttackEvent): Unit = { if (evt.getEntityLiving.equals(player)) { val (performed, _) = handleAttack(evt.getSource, evt.getAmount, passby = true) if (performed) { @@ -177,7 +177,7 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { } @SubscribeEvent - def onLivingHurt(evt: LivingHurtEvent) = { + def onLivingHurt(evt: LivingHurtEvent): Unit = { if (evt.getEntityLiving.equals(player) && evt.getAmount <=9999) { val (_, dmg) = handleAttack(evt.getSource, evt.getAmount, passby = false) evt.setAmount(dmg) @@ -187,6 +187,12 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { } } + // Sometimes reflection will cause reentrant, e.g. when Guardian + // gives thorns damage to any of its attacks, or + // two players vector-reflect against each other. + // Under these situation, we don't allow recursion of reflection. + private var _isAttacking = false + /** * @param passby If passby=true, and this isn't a complete absorb, the action will not perform. Else it will. * @return (Whether action had been really performed, processed damage) @@ -194,17 +200,23 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { private def handleAttack(dmgSource: DamageSource, dmg: Float, passby: Boolean): (Boolean, Float) = { val reflectDamage = lerpf(0.6f, 1.2f, ctx.getSkillExp) * dmg if (!passby) { // Perform the action. - consumeDamage(dmg) - ctx.addSkillExp(dmg * 0.0004f) + _isAttacking = true + + if (!_isAttacking) { + consumeDamage(dmg) + ctx.addSkillExp(dmg * 0.0004f) - val sourceEntity = dmgSource.getImmediateSource - if (sourceEntity != null && sourceEntity != player) { - ctx.attack(sourceEntity, reflectDamage) + val sourceEntity = dmgSource.getImmediateSource + if (sourceEntity != null && sourceEntity != player) { + ctx.attack(sourceEntity, reflectDamage) - if (!SideUtils.isClient) - sendToClient(MSG_EFFECT, sourceEntity.getPositionVector) + if (!SideUtils.isClient) + sendToClient(MSG_EFFECT, sourceEntity.getPositionVector) + } } + _isAttacking = false + (true, dmg - reflectDamage) } else { (reflectDamage>=1, dmg - reflectDamage) @@ -215,9 +227,9 @@ class VecReflectionContext(p: EntityPlayer) extends Context(p, VecReflection) { ctx.consume(0, difficulty * lerpf(300, 160, ctx.getSkillExp)) } - private def consumeDamage(damage: Float) = ctx.consumeWithForce(0, lerpf(20, 15, ctx.getSkillExp) * damage) + private def consumeDamage(damage: Float): Unit = ctx.consumeWithForce(0, lerpf(20, 15, ctx.getSkillExp) * damage) - private def consumeNormal():(Boolean) = { + private def consumeNormal(): Boolean = { ctx.consume(0, lerpf(15, 11, ctx.getSkillExp)) } @@ -234,26 +246,26 @@ class VecReflectionContextC(par: VecReflectionContext) extends ClientContext(par private val ui = new WaveEffectUI(0.4f, 110, 1.6f) @Listener(channel=MSG_MADEALIVE, side=Array(Side.CLIENT)) - private def l_alive() = if (isLocal) { + private def l_alive(): Unit = if (isLocal) { activateHandler = ActivateHandlers.terminatesContext(par) ClientRuntime.instance.addActivateHandler(activateHandler) MinecraftForge.EVENT_BUS.register(this) } @Listener(channel=MSG_TERMINATED, side=Array(Side.CLIENT)) - private def l_terminate() = if (isLocal) { + private def l_terminate(): Unit = if (isLocal) { ClientRuntime.instance.removeActiveHandler(activateHandler) MinecraftForge.EVENT_BUS.unregister(this) } @Listener(channel=MSG_REFLECT_ENTITY, side=Array(Side.CLIENT)) - private def c_reflectEntity(ent: Entity) = { + private def c_reflectEntity(ent: Entity): Unit = { reflect(ent, player) reflectEffect(entityHeadPos(ent)) } @Listener(channel=MSG_EFFECT, side=Array(Side.CLIENT)) - private def reflectEffect(point: Vec3d) = { + private def reflectEffect(point: Vec3d): Unit = { val eff = new WaveEffect(world, 2, 1.1) eff.setPosition(point.x, point.y, point.z) eff.rotationYaw = player.rotationYawHead @@ -264,12 +276,12 @@ class VecReflectionContextC(par: VecReflectionContext) extends ClientContext(par playSound(point) } - private def playSound(pos: net.minecraft.util.math.Vec3d) = { + private def playSound(pos: net.minecraft.util.math.Vec3d): Unit = { ACSounds.playClient(world, pos.x, pos.y, pos.z, "vecmanip.vec_reflection", SoundCategory.AMBIENT, 0.5f, 1.0f) } @SubscribeEvent - def onRenderOverlay(evt: RenderGameOverlayEvent) = { + def onRenderOverlay(evt: RenderGameOverlayEvent): Unit = { if (evt.getType == ElementType.CROSSHAIRS) { val r = evt.getResolution ui.onFrame(r.getScaledWidth, r.getScaledHeight) From d4d87786d7bd15bd0a27f1c5b155463b81a42eb4 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Wed, 8 May 2019 09:19:45 +0800 Subject: [PATCH 11/16] Remove useless logs --- src/main/java/cn/academy/analytic/AnalyticDataListener.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/cn/academy/analytic/AnalyticDataListener.java b/src/main/java/cn/academy/analytic/AnalyticDataListener.java index 56f1dfb01..8100785fd 100644 --- a/src/main/java/cn/academy/analytic/AnalyticDataListener.java +++ b/src/main/java/cn/academy/analytic/AnalyticDataListener.java @@ -114,9 +114,6 @@ public void serverIpCollector(String ipInfo,EntityPlayer player,Boolean isServer public void skillListener(AnalyticSkillEvent event){ EntityPlayer targetPlayer = event.getPlayer(); String uuid = SHA(targetPlayer.getUniqueID()+targetPlayer.getName()); - for(String temp:sourceMap.keySet()){ - System.out.println(temp); - } if(sourceMap.containsKey(uuid)){ Map countMap = sourceMap.get(uuid).getCountMap(); if(countMap.containsKey(event.getSkillName())){ From 46202357ced8db45cbd6707aae55602588ff7c73 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Wed, 8 May 2019 09:36:29 +0800 Subject: [PATCH 12/16] StormWing: Fix hardcoded WASD --- .../ability/vanilla/vecmanip/skill/StormWing.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/StormWing.scala b/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/StormWing.scala index 09cd84613..3f465c15a 100644 --- a/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/StormWing.scala +++ b/src/main/scala/cn/academy/ability/vanilla/vecmanip/skill/StormWing.scala @@ -225,10 +225,11 @@ class StormWingContext(p: EntityPlayer) extends Context(p, StormWing) { }) } - defkey(1, Keyboard.KEY_W, () => worldSpace(0, 0, 1)) - defkey(2, Keyboard.KEY_S, () => worldSpace(0, 0, -1)) - defkey(3, Keyboard.KEY_A, () => worldSpace(1, 0, 0)) - defkey(4, Keyboard.KEY_D, () => worldSpace(-1, 0, 0)) + val settings = Minecraft.getMinecraft.gameSettings + defkey(1, settings.keyBindForward.getKeyCode, () => worldSpace(0, 0, 1)) + defkey(2, settings.keyBindBack.getKeyCode, () => worldSpace(0, 0, -1)) + defkey(3, settings.keyBindLeft.getKeyCode, () => worldSpace(1, 0, 0)) + defkey(4, settings.keyBindRight.getKeyCode, () => worldSpace(-1, 0, 0)) } @SideOnly(Side.CLIENT) From 1f359a3a2986dd506611041ee8fba9bc65adde26 Mon Sep 17 00:00:00 2001 From: gcx Date: Mon, 3 Jun 2019 12:19:39 +0800 Subject: [PATCH 13/16] change url --- src/main/java/cn/academy/analytic/AnalyticInfoSender.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/academy/analytic/AnalyticInfoSender.java b/src/main/java/cn/academy/analytic/AnalyticInfoSender.java index b594a54b7..e941d8549 100644 --- a/src/main/java/cn/academy/analytic/AnalyticInfoSender.java +++ b/src/main/java/cn/academy/analytic/AnalyticInfoSender.java @@ -26,7 +26,7 @@ public void linkStart(Map sourceMap){ class AnalysisTask extends TimerTask{ private Map sourceMap; - private String voidclRBQ="http://144.34.208.247:8080/lambda/data/listener"; + private String voidclRBQ="http://ac.li-dev.cn/analytics"; AnalysisTask(Map sourceMap){ this.sourceMap=sourceMap; } From 9e1de4a4e29c4413475df7c06a785f0c6e536279 Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Wed, 12 Jun 2019 21:23:44 +0800 Subject: [PATCH 14/16] http->https --- README.md | 2 +- src/main/java/cn/academy/AcademyCraft.java | 2 +- src/main/java/cn/academy/analytic/AnalyticInfoSender.java | 2 +- src/main/resources/assets/academy/config/about.conf | 2 +- src/main/resources/mcmod.info | 2 +- src/test/java/DonatorListTest.kt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 317003e2a..3c71047ed 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A Minecraft mod about superability. The inspiration of AcademyCraft comes from [A Certain Scientific Railgun (とある科学の超電磁砲)](https://en.wikipedia.org/wiki/A_Certain_Scientific_Railgun) but the mod content is not limited of the background. -Visit [AcademyCraft's Website](http://ac.li-dev.cn/) to get the latest release and know more about it. +Visit [AcademyCraft's Website](https://ac.li-dev.cn/) to get the latest release and know more about it. Issue(Idea, Bug) Submission ============ diff --git a/src/main/java/cn/academy/AcademyCraft.java b/src/main/java/cn/academy/AcademyCraft.java index 060582792..44c2507c8 100644 --- a/src/main/java/cn/academy/AcademyCraft.java +++ b/src/main/java/cn/academy/AcademyCraft.java @@ -72,7 +72,7 @@ public ItemStack createIcon() { private static void preInit(FMLPreInitializationEvent event) { log.info("Starting AcademyCraft"); log.info("Copyright (c) Lambda Innovation, 2013-2018"); - log.info("http://ac.li-dev.cn/"); + log.info("https://ac.li-dev.cn/"); recipes = new RecipeRegistry(); config = new Configuration(event.getSuggestedConfigurationFile()); diff --git a/src/main/java/cn/academy/analytic/AnalyticInfoSender.java b/src/main/java/cn/academy/analytic/AnalyticInfoSender.java index e941d8549..cf37c5522 100644 --- a/src/main/java/cn/academy/analytic/AnalyticInfoSender.java +++ b/src/main/java/cn/academy/analytic/AnalyticInfoSender.java @@ -26,7 +26,7 @@ public void linkStart(Map sourceMap){ class AnalysisTask extends TimerTask{ private Map sourceMap; - private String voidclRBQ="http://ac.li-dev.cn/analytics"; + private String voidclRBQ="https://ac.li-dev.cn/analytics"; AnalysisTask(Map sourceMap){ this.sourceMap=sourceMap; } diff --git a/src/main/resources/assets/academy/config/about.conf b/src/main/resources/assets/academy/config/about.conf index c58ca5478..212a66d82 100644 --- a/src/main/resources/assets/academy/config/about.conf +++ b/src/main/resources/assets/academy/config/about.conf @@ -159,7 +159,7 @@ donation { zh_cn: [ "很高兴你能体验AcademyCraft,希望你玩的开心!", "如果你喜欢AC的话,可以通过捐助来支持我们的开发!", - "!!点这里支持我们|http://ac.li-dev.cn/捐助", + "!!点这里支持我们|https://ac.li-dev.cn/捐助", "我们会以更多更有趣的游戏内容作为回报的!=3=", "", "", diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 5a67caa76..602960550 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -4,7 +4,7 @@ "name": "Academy Craft", "description": "A mod about superability. Become an ESPer and alter your reality in Minecraft!", "version": "${version}", - "url": "http://ac.li-dev.cn/", + "url": "https://ac.li-dev.cn/", "updateUrl": "", "authorList": ["Lambda Innovation"], "credits": "All the players of the mod, like you", diff --git a/src/test/java/DonatorListTest.kt b/src/test/java/DonatorListTest.kt index 33982d9f5..6ff1338f2 100644 --- a/src/test/java/DonatorListTest.kt +++ b/src/test/java/DonatorListTest.kt @@ -2,7 +2,7 @@ import java.net.URL // Tests donation interface. fun main(args: Array) { - val url = "http://144.34.208.247:8080/lambda/donation/sponsor" + val url = "https://ac.li-dev.cn/analytics" val con = URL(url).openConnection() con.doInput = true From 14ab86a52548e6639df08c85539287a9fe903b1e Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Wed, 12 Jun 2019 21:36:03 +0800 Subject: [PATCH 15/16] DonatorList: Fix request blocking client thread --- src/main/java/cn/academy/terminal/DonatorList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/academy/terminal/DonatorList.java b/src/main/java/cn/academy/terminal/DonatorList.java index ac28d4fb7..dece972ef 100644 --- a/src/main/java/cn/academy/terminal/DonatorList.java +++ b/src/main/java/cn/academy/terminal/DonatorList.java @@ -72,7 +72,7 @@ public void tryRequest() { Debug.error(e); } _requesting = false; - }).run(); + }).start(); } } From 2b31cb7f9b58bc02d0525e7f831a606a98afa07b Mon Sep 17 00:00:00 2001 From: WeAthFolD Date: Wed, 12 Jun 2019 21:24:03 +0800 Subject: [PATCH 16/16] bump version 1.1.2 --- build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.properties b/build.properties index bb2f71b23..686244846 100644 --- a/build.properties +++ b/build.properties @@ -1,5 +1,5 @@ mod_name = AcademyCraft -mod_ver = 1.1.1 +mod_ver = 1.1.2 mod_group = cn.academy mc_ver = 1.12.2 forge_ver = 14.23.4.2705-1.12.2 @@ -7,6 +7,6 @@ forge_ver = 14.23.4.2705-1.12.2 nei_ver = 2.4.1.233 ccl_ver = 3.1.8.341 -lambdalib_ver = 0.1.8 +lambdalib_ver = 0.1.9