Jump to content

[1.10.2] [Scala] Capabilities clashing with each other (SOLVED)


tripl3dogdare

Recommended Posts

So I'm working on a fairly large mod in Scala, and I have two different capabilities, one for handling mana and the other for handling a custom level/exp system. However, it seems like I've done something wrong, as Forge appears to try to connect an instance of the mana handler to where there should be a level handler.

 

ServerProxy (usually called CommonProxy, I'm weird)

 

class ServerProxy {
def preInit {
	CapabilityManager.INSTANCE.register(classOf[ManaHandler], ManaHandler.getStorageInstance, ManaHandler.getHandlerFactory)
	CapabilityManager.INSTANCE.register(classOf[LevelHandler], LevelHandler.getStorageInstance, LevelHandler.getHandlerFactory)
	MinecraftForge.EVENT_BUS.register(new ChuuniEventHandler)
}
}

 

 

Relevant event handler code

 

@SubscribeEvent def addPlayerCapabilities(e:AttachCapabilitiesEvent.Entity) {
if(e.getEntity.isInstanceOf[EntityPlayer]) {
	e.addCapability(new ResourceLocation(ChuuniMod.MODID, "ManaHandler"), ManaHandler.getHandlerInstance)
	e.addCapability(new ResourceLocation(ChuuniMod.MODID, "LevelHandler"), LevelHandler.getHandlerInstance)
}
}

 

 

Relevant capability code

 

object LevelHandler {
@CapabilityInject(classOf[LevelHandler]) final val CAP:Capability[LevelHandler] = null

def instanceFor(player:EntityPlayer) = player.getCapability(CAP, null)
def getHandlerInstance = new DefaultLevelHandler
def getStorageInstance = new DefaultLevelHandler.Storage
def getHandlerFactory = new Callable[DefaultLevelHandler] { def call = new DefaultLevelHandler }
}

object ManaHandler {
@CapabilityInject(classOf[ManaHandler]) final val CAP:Capability[ManaHandler] = null

def instanceFor(player:EntityPlayer) = player.getCapability(CAP, null)
def getHandlerInstance = new DefaultManaHandler
def getStorageInstance = new DefaultManaHandler.Storage
def getHandlerFactory = new Callable[DefaultManaHandler] { def call = new DefaultManaHandler }
}

 

 

There is also an abstract class LevelHandler, but none of it's code should really be relevant. DefaultLevelHandler is a typical double-inheritance from LevelHandler and ICapabilitySerializable, and it's Storage is fairly standard as well. The same is true of ManaHandler's parts.

 

Can you spot my error? I'm completely stumped. Thanks!

Link to comment
Share on other sites

Ah yes, sorry. The game crashes with this error when I try to load a world:

 

java.lang.ClassCastException: chuunimod.capabilities.DefaultManaHandler cannot be cast to chuunimod.capabilities.LevelHandler
at chuunimod.capabilities.LevelHandler$.instanceFor(LevelHandler.scala:58)
at chuunimod.gui.GuiChuuniOverlay.onRenderGameOverlay(GuiChuuniOverlay.scala:22)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_9_GuiChuuniOverlay_onRenderGameOverlay_Post.invoke(.dynamic)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)
at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:168)
at net.minecraftforge.client.GuiIngameForge.post(GuiIngameForge.java:888)
at net.minecraftforge.client.GuiIngameForge.renderExperience(GuiIngameForge.java:586)
at net.minecraftforge.client.GuiIngameForge.renderGameOverlay(GuiIngameForge.java:167)
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1125)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1139)
at net.minecraft.client.Minecraft.run(Minecraft.java:406)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)

 

Full crash report:

 

---- Minecraft Crash Report ----
// Don't be sad. I'll do better next time, I promise!

Time: 10/7/16 5:31 PM
Description: Unexpected error

java.lang.ClassCastException: chuunimod.capabilities.DefaultManaHandler cannot be cast to chuunimod.capabilities.LevelHandler
at chuunimod.capabilities.LevelHandler$.instanceFor(LevelHandler.scala:58)
at chuunimod.gui.GuiChuuniOverlay.onRenderGameOverlay(GuiChuuniOverlay.scala:22)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_9_GuiChuuniOverlay_onRenderGameOverlay_Post.invoke(.dynamic)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)
at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:168)
at net.minecraftforge.client.GuiIngameForge.post(GuiIngameForge.java:888)
at net.minecraftforge.client.GuiIngameForge.renderExperience(GuiIngameForge.java:586)
at net.minecraftforge.client.GuiIngameForge.renderGameOverlay(GuiIngameForge.java:167)
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1125)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1139)
at net.minecraft.client.Minecraft.run(Minecraft.java:406)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Client thread
Stacktrace:
at chuunimod.capabilities.LevelHandler$.instanceFor(LevelHandler.scala:58)
at chuunimod.gui.GuiChuuniOverlay.onRenderGameOverlay(GuiChuuniOverlay.scala:22)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_9_GuiChuuniOverlay_onRenderGameOverlay_Post.invoke(.dynamic)
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)
at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:168)
at net.minecraftforge.client.GuiIngameForge.post(GuiIngameForge.java:888)
at net.minecraftforge.client.GuiIngameForge.renderExperience(GuiIngameForge.java:586)
at net.minecraftforge.client.GuiIngameForge.renderGameOverlay(GuiIngameForge.java:167)

-- Affected level --
Details:
Level name: MpServer
All players: 1 total; [EntityPlayerSP['tripl3_'/949, l='MpServer', x=8.50, y=65.00, z=8.50]]
Chunk stats: MultiplayerChunkCache: 0, 0
Level seed: 0
Level generator: ID 00 - default, ver 1. Features enabled: false
Level generator options: 
Level spawn location: World: (-116,64,124), Chunk: (at 12,4,12 in -8,7; contains blocks -128,0,112 to -113,255,127), Region: (-1,0; contains chunks -32,0 to -1,31, blocks -512,0,0 to -1,255,511)
Level time: 0 game time, 0 day time
Level dimension: 0
Level storage version: 0x00000 - Unknown?
Level weather: Rain time: 0 (now: false), thunder time: 0 (now: false)
Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: false
Forced entities: 1 total; [EntityPlayerSP['tripl3_'/949, l='MpServer', x=8.50, y=65.00, z=8.50]]
Retry entities: 0 total; []
Server brand: fml,forge
Server type: Integrated singleplayer server
Stacktrace:
at net.minecraft.client.multiplayer.WorldClient.addWorldInfoToCrashReport(WorldClient.java:451)
at net.minecraft.client.Minecraft.addGraphicsAndWorldToCrashReport(Minecraft.java:2779)
at net.minecraft.client.Minecraft.run(Minecraft.java:435)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)

-- System Details --
Details:
Minecraft Version: 1.10.2
Operating System: Windows 10 (amd64) version 10.0
Java Version: 1.8.0_74, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 598666392 bytes (570 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
JVM Flags: 4 total; -Xincgc -Xmx1024M -Xms1024M -Xbootclasspath/a:C:\Program Files (x86)\Scala IDE\plugins\org.scala-lang.scala-library_2.11.8.v20160304-115712-1706a37eb8.jar;C:\Program Files (x86)\Scala IDE\plugins\org.scala-lang.scala-reflect_2.11.8.v20160304-115712-1706a37eb8.jar
IntCache: cache: 0, tcache: 0, allocated: 13, tallocated: 95
FML: MCP 9.32 Powered by Forge 12.18.1.2095 4 mods loaded, 4 mods active
States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
UCHIJAAAA	mcp{9.19} [Minecraft Coder Pack] (minecraft.jar) 
UCHIJAAAA	FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.10.2-12.18.1.2095.jar) 
UCHIJAAAA	Forge{12.18.1.2095} [Minecraft Forge] (forgeSrc-1.10.2-12.18.1.2095.jar) 
UCHIJAAAA	chuunimod{INDEV} [ChuuniMod] (bin) 
Loaded coremods (and transformers): 
GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 358.91' Renderer: 'GeForce GTX 750 Ti/PCIe/SSE2'
Launched Version: 1.10.2
LWJGL: 2.9.4
OpenGL: GeForce GTX 750 Ti/PCIe/SSE2 GL version 4.5.0 NVIDIA 358.91, NVIDIA Corporation
GL Caps: Using GL 1.3 multitexturing.
Using GL 1.3 texture combiners.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Shaders are available because OpenGL 2.1 is supported.
VBOs are available because OpenGL 1.5 is supported.

Using VBOs: Yes
Is Modded: Definitely; Client brand changed to 'fml,forge'
Type: Client (map_client.txt)
Resource Packs: 
Current Language: English (US)
Profiler Position: N/A (disabled)
CPU: 4x Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz

 

 

All I'm doing is trying to access the handlers via the instanceFor method to render their information to a GUI.

Link to comment
Share on other sites

Mana:

class DefaultManaHandler(cur:Float=0,max:Float=250,regen:Float=.25f) extends ManaHandler(cur,max,regen) with ICapabilitySerializable[NBTTagCompound] {
def hasCapability(capability:Capability[_], f:EnumFacing) = capability == ManaHandler.CAP
def getCapability[T](capability:Capability[T], f:EnumFacing) = { if(capability == ManaHandler.CAP) this else null }.asInstanceOf[T]

def serializeNBT:NBTTagCompound = new NBTManaHandler(this).nbt
def deserializeNBT(nbt:NBTTagCompound) = new NBTManaHandler(nbt).copyTo(this)
}

object DefaultManaHandler {
class Storage extends IStorage[ManaHandler] {
	def writeNBT(cap:Capability[ManaHandler], ins:ManaHandler, f:EnumFacing) = ins.asInstanceOf[DefaultManaHandler].serializeNBT
	def readNBT(cap:Capability[ManaHandler], ins:ManaHandler, f:EnumFacing, nbt:NBTBase) = ins.asInstanceOf[DefaultManaHandler].deserializeNBT(nbt.asInstanceOf[NBTTagCompound])
}
}

 

Levels:

class DefaultLevelHandler(lvl:Int=1,xp:Float=0) extends LevelHandler(lvl,xp) with ICapabilitySerializable[NBTTagCompound] {
def hasCapability(capability:Capability[_], f:EnumFacing) = capability == LevelHandler.CAP
def getCapability[T](capability:Capability[T], f:EnumFacing) = { if(capability == LevelHandler.CAP) this else null }.asInstanceOf[T]

def serializeNBT:NBTTagCompound = new NBTLevelHandler(this).nbt
def deserializeNBT(nbt:NBTTagCompound) = new NBTLevelHandler(nbt).copyTo(this)
}

object DefaultLevelHandler {
class Storage extends IStorage[LevelHandler] {
	def writeNBT(cap:Capability[LevelHandler], ins:LevelHandler, f:EnumFacing) = ins.asInstanceOf[DefaultLevelHandler].serializeNBT
	def readNBT(cap:Capability[LevelHandler], ins:LevelHandler, f:EnumFacing, nbt:NBTBase) = ins.asInstanceOf[DefaultLevelHandler].deserializeNBT(nbt.asInstanceOf[NBTTagCompound])
}
}

Link to comment
Share on other sites

Not really sure what you mean by the same class - the capability type is Handler, and the default implementation is DefaultHandler.

 

As to the debugger idea, the only option I have is the Eclipse debugger, which doesn't seem to be up to the task.

Link to comment
Share on other sites

DefaultLevelHandler implements both LevelHandler and ICapabilitySerializable (i.e. ICapabilityProvider)

Ah, ok. Honestly, I've used this structure before and not had any problems with keeping track of it... For brevity's sake I'll leave it for now, especially as I don't think that's where the problem is (the mana handler worked fine before I added the level handler)

Link to comment
Share on other sites

I have only the vaguest idea why, but for some reason that worked. Thank you! My updated code is below for anyone having the same issue.

 

object (x)Handler

object ManaHandler {
def instanceFor(player:EntityPlayer) = player.getCapability(Capabilities.MANA, null)
def getHandlerInstance = new DefaultManaHandler
def getStorageInstance = new DefaultManaHandler.Storage
def getHandlerFactory = new Callable[DefaultManaHandler] { def call = new DefaultManaHandler }
}

object LevelHandler {
def instanceFor(player:EntityPlayer) = player.getCapability(Capabilities.LEVEL, null)
def getHandlerInstance = new DefaultLevelHandler
def getStorageInstance = new DefaultLevelHandler.Storage
def getHandlerFactory = new Callable[DefaultLevelHandler] { def call = new DefaultLevelHandler }
}

 

Capabilities.java

public class Capabilities {
@CapabilityInject(ManaHandler.class) public static final Capability<ManaHandler> MANA = null;
@CapabilityInject(LevelHandler.class) public static final Capability<LevelHandler> LEVEL = null;
}

 

Moral of the story, don't try to inject capabilities into Scala code if you intend to use more than one.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • 20 SLOT DEMO GRATIS PRAGMATIC PLAY x500 RUPIAH ANTI LAG & 20 DEMO SLOT MAHJONG WAYS PG SOFT GRATIS ANTI RUNGKAD KLIK DISINI DAFTAR DISINI SLOT VVIP << KLIK DISINI DAFTAR DISINI SLOT VVIP << KLIK DISINI DAFTAR DISINI SLOT VVIP << KLIK DISINI DAFTAR DISINI SLOT VVIP << SITUS SLOT GACOR 88 MAXWIN X500 HARI INI TERBAIK DAN TERPERCAYA GAMPANG MENANG Dunia Game gacor terus bertambah besar seiring berjalannya waktu, dan sudah tentu dunia itu terus berkembang serta merta bersamaan dengan berkembangnya SLOT GACOR sebagai website number #1 yang pernah ada dan tidak pernah mengecewakan sekalipun. Dengan banyaknya member yang sudah mempercayakan untuk terus menghasilkan uang bersama dengan SLOT GACOR pastinya mereka sudah percaya untuk bermain Game online bersama dengan kami dengan banyaknya testimoni yang sudah membuktikan betapa seringnya member mendapatkan jackpot besar yang bisa mencapai ratusan juta rupiah. Best online Game website that give you more money everyday, itu lah slogan yang tepat untuk bermain bersama SLOT GACOR yang sudah pasti menang setiap harinya dan bisa menjadikan bandar ini sebagai patokan untuk mendapatkan penghasilan tambahan yang efisien dan juga sesuatu hal yang fix setiap hari nya. Kami juga mendapatkan julukan sebagai Number #1 website bocor yang berarti terus memberikan member uang asli dan jackpot setiap hari nya, tidak lupa bocor itu juga bisa diartikan dalam bentuk berbagi promosi untuk para official member yang terus setia bermain bersama dengan kami. Berbagai provider Game terus bertambah banyak setiap harinya dan terus melakukan support untuk membuat para official member terus bisa menang dan terus maxwin dalam bentuk apapun maka itu langsung untuk feel free to try yourself, play with SLOT GACOR now or never !
    • BOCORAN POLA SLOT GACOR MAHJONG WAYS MAXWIN x500 PETIR MERAH HARI INI HINGGA MALAM INI KLIK DISINI DAFTAR SLOT VVIP << KLIK DISINI DAFTAR SLOT VVIP << KLIK DISINI DAFTAR SLOT VVIP << KLIK DISINI DAFTAR SLOT VVIP << SITUS SLOT GACOR 88 MAXWIN X500 HARI INI TERBAIK DAN TERPERCAYA GAMPANG MENANG Dunia Game gacor terus bertambah besar seiring berjalannya waktu, dan sudah tentu dunia itu terus berkembang serta merta bersamaan dengan berkembangnya SLOT GACOR sebagai website number #1 yang pernah ada dan tidak pernah mengecewakan sekalipun. Dengan banyaknya member yang sudah mempercayakan untuk terus menghasilkan uang bersama dengan SLOT GACOR pastinya mereka sudah percaya untuk bermain Game online bersama dengan kami dengan banyaknya testimoni yang sudah membuktikan betapa seringnya member mendapatkan jackpot besar yang bisa mencapai ratusan juta rupiah. Best online Game website that give you more money everyday, itu lah slogan yang tepat untuk bermain bersama SLOT GACOR yang sudah pasti menang setiap harinya dan bisa menjadikan bandar ini sebagai patokan untuk mendapatkan penghasilan tambahan yang efisien dan juga sesuatu hal yang fix setiap hari nya. Kami juga mendapatkan julukan sebagai Number #1 website bocor yang berarti terus memberikan member uang asli dan jackpot setiap hari nya, tidak lupa bocor itu juga bisa diartikan dalam bentuk berbagi promosi untuk para official member yang terus setia bermain bersama dengan kami. Berbagai provider Game terus bertambah banyak setiap harinya dan terus melakukan support untuk membuat para official member terus bisa menang dan terus maxwin dalam bentuk apapun maka itu langsung untuk feel free to try yourself, play with SLOT GACOR now or never !
    • Museumbola merupakan wadah judi online terkhusus untuk sbobet atau judi bola. Dengan daftar dan deposit menggunakan BANK BCA, Anda berkesempatan mendapatkan prediksi jitu pertandingan secara update setiap hari yang bisa anda jadikan acuan untuk bermain judi bola. Hanya dengan 10 ribu rupiah dan anda bermain Mix Parlay menggunakan prediksi yang telah di sediakan oleh kami, anda akan memenangkan jutaan rupiah. Yuk segera klik DAFTAR sekarang juga.
    • I was just trying to play my modded world when i randomly got this crash for no reason. I sorted through like every mod and eventually I realized it was LLibrary but I can't seem to find a solution to fix the crashing. I can't lose the world that I have that uses this mod please help me. Here's the report: https://pastebin.com/0D00B79i If anyone has a solution please let me know.  
    • 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑   Daftar Slot Ligawin88 adalah bocoran slot rekomendasi gacor dari Ligawin88 yang bisa anda temukan di SLOT Ligawin88. Situs SLOT Ligawin88 hari ini yang kami bagikan di sini adalah yang terbaik dan bersiaplah untuk mengalami sensasi tak terlupakan dalam permainan slot online. Temukan game SLOT Ligawin88 terbaik dengan 100 pilihan provider ternama yang dipercaya akan memberikan kepuasan dan kemenangan hari ini untuk meraih x500. RTP SLOT Ligawin88 merupakan SLOT Ligawin88 hari ini yang telah menjadi pilihan utama bagi pemain judi online di seluruh Indonesia. Setiap harinya jutaan pemain memasuki dunia maya untuk memperoleh hiburan seru dan kemenangan besar dalam bermain slot dengan adanya bocoran RTP SLOT Ligawin88. Tidak ada yang lebih menyenangkan daripada mengungguli mesin slot dan meraih jackpot x500 yang menggiurkan di situs SLOT Ligawin88 hari ini yang telah disediakan SLOT Ligawin88. Menangkan jackpot besar x500 rajanya maxwin dari segala slot dan raih kemenangan spektakuler di situs Ligawin88 terbaik 2024 adalah tempat yang menyediakan mesin slot dengan peluang kemenangan lebih tinggi daripada situs slot lainnya. Bagi anda yang mencari pengalaman judi slot paling seru dan mendebarkan, situs bo SLOT Ligawin88 terbaik 2024 adalah pilihan yang tepat. Jelajahi dunia slot online melalui situs SLOT Ligawin88 di link SLOT Ligawin88.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.