From 9991f4a5fc616b19a6e6e537b84287b29a0645d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 3 Jun 2014 16:58:11 +0200 Subject: [PATCH] Should fix crash in native lib by avoiding the crashing JNLua metacall. Rendering floppy labels on the floppy in the inventory. --- assets/items.psd | Bin 341564 -> 345458 bytes .../assets/opencomputers/lua/kernel.lua | 4 +- .../textures/items/disk_floppy.png | Bin 507 -> 467 bytes src/main/scala/li/cil/oc/client/Proxy.scala | 3 +- .../client/renderer/item/FloppyRenderer.scala | 50 ++++++++++++++++++ .../renderer/item/UpgradeRenderer.scala | 2 +- .../machine/NativeLuaArchitecture.scala | 6 ++- .../component/machine/luac/UserdataAPI.scala | 8 +++ .../component/machine/luaj/UserdataAPI.scala | 6 +++ 9 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 src/main/scala/li/cil/oc/client/renderer/item/FloppyRenderer.scala diff --git a/assets/items.psd b/assets/items.psd index 4b5a90b2a9d23ee2fd988a91aaef8f86f9fd150c..111d91668d6da7533c2dff121813e2563e62b278 100644 GIT binary patch delta 1924 zcmai!c~BE~6vuzRWHBniaA;c;Iiz-46iGmiU;!ZpL_n~J9CCS5ib;x!RvpOTfvq4& z1FV9P!*a9)5CW`#I(AfQ1r=pPNPtM8Do4Q94ItNcfr8>6x-)O~_kQo~`@Hv^{r#@> zE&lh+l5>WO^1E!DTs;s3Og=A?*R&)%%oow1j^1;(lSOAu6N+5Lt99$cd0A6wpHF6q z#ZoKy3TjxHGA*_;Eo@mfwoFTr1(iK_M|y<%1J!`bv9NSxI&z&jTt}`2i^aBPv2C0; zY*@>-X0w?#QcYUtZc*lfI76<}2NSuXWHXz$04rN_OKBFv0~&q=@ZNV*t!6R)kiL!( zn@jU9t%Puas6KNGJR{Z5I*w65H`?zHMW}c))D*SVYogc51vVZCPeTgm!N}Mq3Iu4j zFH8|Jay3!KSCE1A1;X=?+*SI+6ihb+Vq~szs*WiBg(hmM1{o-sqa}67je=;RFVv=h zeoTKC#5K*0d8DF{G%wP!NP7i98u>Eb0zLzfXeR!m`?+#BAzt5jI=i}a0fgw4Fvx)b z!^0p#$IK5xCv}*KMG4^`MaU??i!+~8*Nupq@u-L1 zu`^#1;1&VcJ2xGr>&K?LZ0bqrsFXzRJ!Btjy0~jWae7d~&^F7r!}})DFH5* zOlVm*C8DZy0?1T&U3b2^>1Y`rGm`N3jan|T%dk^7h{u=nJ-dY-E@M0Y9H|QNBEZGr za=h|yhlN*yUvyQd%Hjq}j@gAh@|C5JF?_WX4hw~{4ErY&>Q73_?{&8fc{h~?G%;i` z`7O$WpHLzTZih*3>JN_gjtGAlG5E*z%GI+KQem!YeN~cQhjqDUxbS$(gUfk7hYM5F zSV4lSq6595>+GyhW`N>QTluQBzOka8yb7MCCi%&|$1AN{MogFY^Pel5s|3YK)sprM zUXHL~K-#VsiD~ulZx8n4ePasW$8FNF6;f678-v##IfGs1V;AEGsoT$1s++GVL)rNa z@}On{bO?P49}~bSiSAq>IcEsJh$~VQr*w9W2j8o`QGbY4d)j}nP|ar_53icY&3`G7 zcS|Rh9I2`Plw*0-y#Hh!eMF$EY?ui1Ft1sJHSX^n!P4y?wAwZ8TB`7{9JwzSC5*Sn z=~fq|^r;-g*aX%+I;_`zyf3FUzU+XYW@(tmC8bov1n;Az7pR69Cy%;q zvxW=U3Y-BKtOI6X9{S1{F+!Q%h#uC7Qwx{TC>CC8-?UKBbWOyLPP=;dE^?Nes7KLZcm#WtfvTlC3qD zijh?OE$fxT`>e0mBkog}r1kG$9<6@|v&?Y@gOQk1?-8cv!pOOz-(mt8Y9?qWAJLgR zSMlVwnc)Aq`~-7>I%tsqSv5OcmtclEJ=~7(kyst{*$HHHfhPz6oJn1=u9L_RB>inO ze%!P_8~+ixv*KN)O;AN4qEDl|ReH;ZMaD>xZ!%{~kOG>Z9c}NFAO$o*E!q*|kE?hT f+oeF1X0ydenKsV0LW(op%Exs%iqW;ym@EGS+Dt4o delta 1921 zcmb7Ddr%Wc9KOq4P?47+FL@+N8Ad=rBMjhx4+c~o0+xbE0p%fR#HfgjP)OA(m4etg zkvC*5P67j6YXA*T{{UzM0Iq4AQI&_t3%R$kuE2UV6~=c|fxeW5j|ONFoo;WW0DyHl)cAMy~;a3-l3-_e(gG zh8YM$tRV@!rAIX}CFp@f1QT(Eh#>$dBsyayU?IBW~@&VG4hpENV9 z!uY#$B3kuubrPEjMTP#B=+4ZxPJYfBIOrmg(s4lRPG-o1Nny_m_G=GuO?Q9ot1!2+ z2Xxc!bKa%V-F>WFMxO%?QrF4%);MH8LR? zH;R*~DeYOMJB3Zs6MW15#;iE+iwSpnI^>m?3%w=x#oTIccnnjOYP0&42eX|bvb4(0 z&51hIBI}tHv^=XkzAQ4k?_O>hZ*^i-T5n7o4s3~0u4GhNI`z5W0Jl$ywr)3$9E%qp z^xoOsHM-v}!!_M_gGsMPPic#~IDh;RGIB(~!U6Y>`=rT#WEt(|H$SEKCFn|`N7I|H zR&ia%t?t;EG6#sgTrxbD)M1T66@XG9khNeJ}VbXyCwux zH+YHTK8doa;SKLgeB_M@6YeJcTA29(UdOndZ?Ws2fRv zx{(c0tDZca^9?(DwtTcN4m(qw6>QjGQO{@!lPA^zvP3 z6B>RGT8r9pp{rVwk0(o(%ZK4| za~(1*cpa`(sd0ExiEg68p85;x8XIwZO~9H-B><~cXbu$)SfIkSCZ=#4ea3@bb#(20 zi0cmE0ItN*B}~{5HLr*5iRsPuYMhwE)oL`b9!|%)R>0Sn%qD;l1Qc^&4bh??*lrH? zi=fZ2EraL9P7eMOyEGWygRY{I%`nRlIQa_#8U-*yfz0_>1ZB;`;&j$$EPN^Cxe9pA zK71pEoQ}O_!ao_JyAXI{Q78}vY?-zI`@R4k1BpE1-@I@p|5Pu6AFZ5YiXFOx2U}@F zvrMr=Sv=VGtDV6JXN1mkAT$P;pkDIXID`RqXr3Il{)F?@E?8i{55O{~c@PP)P0%JQ Z@~o2)V%wn>6!L#3`yYy9gyOet{sEjubBF){ diff --git a/src/main/resources/assets/opencomputers/lua/kernel.lua b/src/main/resources/assets/opencomputers/lua/kernel.lua index 13967684e..7d18bd210 100644 --- a/src/main/resources/assets/opencomputers/lua/kernel.lua +++ b/src/main/resources/assets/opencomputers/lua/kernel.lua @@ -348,7 +348,9 @@ function wrapSingleUserdata(data) -- without the need of metamethods like __eq, as well as proper reference -- behavior after saving and loading again. for k, v in pairs(wrappedUserdata) do - if v == data then + -- We need a custom 'equals' check for userdata because metamethods on + -- userdata introduced by JNLua tend to crash the game for some reason. + if userdata.equal(v, data) then return k end end diff --git a/src/main/resources/assets/opencomputers/textures/items/disk_floppy.png b/src/main/resources/assets/opencomputers/textures/items/disk_floppy.png index c6aa08ccaa62f06ae2b68420c105a5ee25ce9d78..40d15fa4edaaa56f68c5f207bc66277f69c23e0f 100644 GIT binary patch delta 361 zcmV-v0ha#z1JeVLNq>+~OjJeL+1da9|0yXcMMXt7H#a>!Jz82?L_|bFLP9GmD`H|| z;^N{jFE2koKWJ!ZF)=aYEG#TbOG_vyC|X%rX=!OpOd?F+;NUYeGuqnPHa0fh z-Q8njWB>pEB-dV`ReE3RTGWh`5zS_9vz zPCt2+KB~0lfWQkpugkmWg+Bl|nPYOo$ub8}Fjg`)FwC_q0Cr=Wyv@_tfajQyJ2lCe z0Q6lS*66ba_(y+hU`U_x}p8x{@Vl5O7g}}Vy00000NkvXX Hu0mjf=d_gc delta 397 zcmV;80doG+1N#GzNq?eHOjJex|NlirMJXvMH#avuJv{&b07OJYT3T8{LP9GmD`H|| z;^N}|{{Am7FF!v&F)=Y{XlVTW{NLZ-XJ=<#US2dbG-YLFCGh<_8+S=Ox|Nj_LtsMXW05)_|PE(QbD3SpUe*mG6PB8!g z0If+xK~#9!T*=oOgCGnA;GiNZ4%~KG+d8_p@BeB&c-7AnLc$M?v(RWWn@tDJCKy;c zlx0#%c7@RBC`YAI%2e)@+G+T7P4Q@x;@%aF0|>p)^H%LD`C^6uE3IUqVmd#>a6(Io-|n*iVRJP~09xNJ$B6Q`J5 rd#S;3eZq@;A1lCk8GixH@)KYH0V)@B0@E@500000NkvXXu0mjf-8-&^ diff --git a/src/main/scala/li/cil/oc/client/Proxy.scala b/src/main/scala/li/cil/oc/client/Proxy.scala index cf9adb1a2..0f8cccb5a 100644 --- a/src/main/scala/li/cil/oc/client/Proxy.scala +++ b/src/main/scala/li/cil/oc/client/Proxy.scala @@ -6,7 +6,7 @@ import cpw.mods.fml.common.network.NetworkRegistry import cpw.mods.fml.common.registry.TickRegistry import cpw.mods.fml.relauncher.Side import li.cil.oc.client.renderer.block.BlockRenderer -import li.cil.oc.client.renderer.item.UpgradeRenderer +import li.cil.oc.client.renderer.item.{FloppyRenderer, UpgradeRenderer} import li.cil.oc.client.renderer.tileentity._ import li.cil.oc.client.renderer.{TextBufferRenderCache, WirelessNetworkDebugRenderer} import li.cil.oc.common.{Proxy => CommonProxy, tileentity} @@ -46,6 +46,7 @@ private[oc] class Proxy extends CommonProxy { ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer) MinecraftForgeClient.registerItemRenderer(Items.multi.itemID, UpgradeRenderer) + MinecraftForgeClient.registerItemRenderer(Items.multi.itemID, FloppyRenderer) MinecraftForge.EVENT_BUS.register(gui.Icons) diff --git a/src/main/scala/li/cil/oc/client/renderer/item/FloppyRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/FloppyRenderer.scala new file mode 100644 index 000000000..8fdc379c1 --- /dev/null +++ b/src/main/scala/li/cil/oc/client/renderer/item/FloppyRenderer.scala @@ -0,0 +1,50 @@ +package li.cil.oc.client.renderer.item + +import li.cil.oc.{Settings, api} +import net.minecraftforge.client.IItemRenderer +import net.minecraftforge.client.IItemRenderer.{ItemRendererHelper, ItemRenderType} +import net.minecraft.item.ItemStack +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.entity.{RenderItem, RenderManager} +import net.minecraft.client.gui.ScaledResolution +import org.lwjgl.opengl.GL11 +import scala.collection.convert.WrapAsScala._ +import net.minecraft.util.EnumChatFormatting + +object FloppyRenderer extends IItemRenderer { + val renderItem = new RenderItem() + renderItem.setRenderManager(RenderManager.instance) + + override def handleRenderType(stack: ItemStack, renderType: ItemRenderType) = renderType == ItemRenderType.INVENTORY && { + val descriptor = api.Items.get(stack) + descriptor == api.Items.get("floppy") || + descriptor == api.Items.get("lootDisk") || + descriptor == api.Items.get("openOS") + } + + override def shouldUseRenderHelper(renderType: ItemRenderType, stack: ItemStack, helper: ItemRendererHelper) = false + + override def renderItem(renderType: ItemRenderType, stack: ItemStack, data: AnyRef*) { + val mc = Minecraft.getMinecraft + renderItem.renderItemIntoGUI(null, mc.getTextureManager, stack, 0, 0) + val res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight) + val fontRenderer = renderItem.getFontRendererFromRenderManager + if (fontRenderer != null && res.getScaleFactor > 1) { + GL11.glPushMatrix() + GL11.glTranslatef(4f + 2f / res.getScaleFactor, 9f + 2f / res.getScaleFactor, 0) + GL11.glScalef(1f / res.getScaleFactor, 1f / res.getScaleFactor, 1f) + val maxLength = (res.getScaleFactor * 7.5).toInt + val label = + if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data") && stack.getTagCompound.getCompoundTag(Settings.namespace + "data").hasKey(Settings.namespace + "fs.label")) { + stack.getTagCompound.getCompoundTag(Settings.namespace + "data").getString(Settings.namespace + "fs.label") + } + else "disk" + val lines = fontRenderer.listFormattedStringToWidth(EnumChatFormatting.func_110646_a(label), maxLength).take(math.max(1, res.getScaleFactor / 2)) + for (line <- lines) { + fontRenderer.drawString(line.asInstanceOf[String], 0, 0, 0) + GL11.glTranslatef(0, fontRenderer.FONT_HEIGHT, 0) + } + GL11.glPopMatrix() + } + } +} diff --git a/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala index 331f5cfab..8ca235fef 100644 --- a/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala @@ -13,7 +13,7 @@ import org.lwjgl.opengl.GL11 object UpgradeRenderer extends IItemRenderer { val bounds = AxisAlignedBB.getBoundingBox(-0.1, -0.1, -0.1, 0.1, 0.1, 0.1) - + override def handleRenderType(stack: ItemStack, renderType: ItemRenderType) = renderType == ItemRenderType.EQUIPPED && { val descriptor = api.Items.get(stack) descriptor == api.Items.get("craftingUpgrade") || diff --git a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala index 4f02c46e9..ded56c816 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala @@ -241,7 +241,7 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu else { assert(lua.isThread(1)) // We're expecting the result of a pcall, if anything, so boolean + (result | string). - if (!lua.isBoolean(2) || !(lua.isString(3) || lua.isNil(3))) { + if (!lua.isBoolean(2) || !(lua.isString(3) || lua.isNoneOrNil(3))) { OpenComputers.log.warning("Kernel returned unexpected results.") } // The pcall *should* never return normally... but check for it nonetheless. @@ -251,7 +251,9 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu } else { lua.setTotalMemory(Int.MaxValue) - val error = lua.toString(3) + val error = + if (lua.isJavaObjectRaw(3)) lua.toJavaObjectRaw(3).toString + else lua.toString(3) if (error != null) new ExecutionResult.Error(error) else new ExecutionResult.Error("unknown error") } diff --git a/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala b/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala index 2867dc88f..22f24bf92 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala @@ -103,6 +103,14 @@ class UserdataAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { }) lua.setField(-2, "doc") + lua.pushScalaFunction(lua => { + val value1 = lua.toJavaObjectRaw(1) + val value2 = lua.toJavaObjectRaw(2) + lua.pushBoolean(value1.isInstanceOf[Value] && value2.isInstanceOf[Value] && value1 == value2) + 1 + }) + lua.setField(-2, "equal") + lua.setGlobal("userdata") } } diff --git a/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala b/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala index 297be171b..11a816b84 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala @@ -59,6 +59,12 @@ class UserdataAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) { owner.documentation(() => machine.documentation(value, method)) }) + userdata.set("equal", (args: Varargs) => { + val value1 = args.checkuserdata(1, classOf[Value]) + val value2 = args.checkuserdata(2, classOf[Value]) + LuaValue.valueOf(value1.isInstanceOf[Value] && value2.isInstanceOf[Value] && value1 == value2) + }) + lua.set("userdata", userdata) } }