Jump to content

Recommended Posts

Posted

I recently wrote a python script which modifies the minecraft_server.jar and minecraft.jar files and I was wondering why something like this hasn't been done before. It took me a very long time to figure out how to install Minecraft Forge into the jar file because the file always became corrupted when I tried to do it. Therefore, I thought it would be easier if Minecraft Forge just provided some type of installer like the one below.

 

Here are the files:

Python 3.x: http://pastie.org/5602598

Python 2.7+: http://pastie.org/5602602

 

(The script works on both the client and the server)

 

Posted

If it was an idiot proof app I'd sticky this topic. But meh.

Read the EAQ before posting! OR ELSE!

 

This isn't building better software, its trying to grab a place in the commit list of a highly visible github project.

 

www.forgeessentials.com

 

Don't PM me, I don't check this account unless I have to.

Posted

(Sorry about the double-post)

 

Here is everything:

Source (Python 2.x):

import sys
import os
import glob
import re
import urllib2, urllib
import httplib as httplib
import shutil
import zipfile as z
from PySide.QtGui import *
from PySide.QtCore import *
from io import open

class mainApp(QMainWindow):
  def __init__(self):
    super(mainApp, self).__init__()
    self.initUI()

  def initUI(self):
    self.mwidget = mainWidget()
    self.setCentralWidget(self.mwidget)
    status = self.statusBar()
    status.showMessage(u"Idle.")
    # Set the title
    self.setWindowTitle(u"Minecraft Forge Installer")
    self.resize(450, 180)
    self.show()

class mainWidget(QWidget):
  def __init__(self):
    super(mainWidget, self).__init__()
    self.initUI()

  def initUI(self):
    # Create widgets
    self.input_ent = QLineEdit(self)
    input_btn = QPushButton(u"Select minecraft.jar")
    input_btn.clicked.connect(self.getFile)
    self.minecraft_version_ent = QLineEdit(self)
    run_btn = QPushButton(u"Run")
    run_btn.clicked.connect(self.runEditMJar)
    # Create a layout
    vbox = QVBoxLayout()
    input_hbox = QHBoxLayout()
    input_hbox.addWidget(self.input_ent)
    input_hbox.addWidget(input_btn)
    vbox.addLayout(input_hbox)
    mversion_hbox = QHBoxLayout()
    mversion_hbox.addWidget(QLabel(u"Minecraft Version:"))
    mversion_hbox.addWidget(self.minecraft_version_ent)
    vbox.addLayout(mversion_hbox)
    vbox.addWidget(run_btn)
    # Show the window
    self.setLayout(vbox)
    self.show()

  def getFile(self):
    fname = QFileDialog.getOpenFileName(self, u"minecraft.jar", u".", u"Jar Files (*.jar)")[0]
    self.input_ent.clear()
    self.input_ent.insert(fname)

  def runEditMJar(self):
    fname = self.input_ent.displayText()
    version = self.minecraft_version_ent.displayText()
    if self.parentWidget().statusBar().currentMessage() == u"Idle." and not os.path.exists(u"newzip"):
      self.sayWorking()
      QCoreApplication.processEvents()
      editJar(fname,version)
      self.sayDone()
    else:
      self.parentWidget().statusBar().showMessage(u"Action not allowed.", timeout=2000)

  def sayWorking(self):
    self.parentWidget().statusBar().showMessage(u"Editing Jar File.")

  def sayDone(self):
    self.parentWidget().statusBar().showMessage(u"Done.")

def editJar(filename, mcversion):
  original = z.ZipFile(filename)
  basename = os.path.basename(filename).split(u".")[0]
  forge_name = download_forge(mcversion)
  forge = z.ZipFile(forge_name)
  os.makedirs(u"newzip")
  original.extractall(path=u"newzip")
  forge.extractall(path=u"newzip")
  original.close()
  forge.close()
  for delfile in glob.glob(u"newzip/META-INF/MOJANG*"):
    os.remove(delfile)
  shutil.make_archive(basename, u"zip", u"newzip")
  backup = os.path.dirname(filename) + u"/backup.jar" 
  print u"Backup: {0}, Filename: {1}".format(backup, filename)
  shutil.move(filename, backup)
  shutil.move(basename + u".zip", filename)
  shutil.rmtree(u"newzip")
  os.remove(forge_name)

def use_mirror():
  connection = httplib.HTTPConnection(u"files.minecraftforge.net", 80)
  connection.request(u"OPTIONS", u"*")
  try:
    response = connection.getresponse()
    return False
  except:
    return True

def getversions(it):
  unp_versions = re.compile(u"Build [0-9].[0-9].[0-9].[0-9]*.*[0-9.]*").findall(it)
  p_versions = []
  for build in unp_versions:
    splitone = build.split(u":")
    p_versions.append((splitone[0].split(u" ")[1], splitone[-1][1:]))
  return p_versions

def download_forge(mcversion):
  using_mirror = use_mirror()
  if using_mirror:
    response = urllib2.urlopen(u"http://ken.wingedboot.com/forgemirror/files.minecraftforge.net/").read()
  else:
    response = urllib2.urlopen(u"http://files.minecraftforge.net/").read()
  versions = getversions(response.decode())
  if int(mcversion.replace(u".",u"")) <= 132:
    exit()
  compat_versions = [i[0] for i in versions if i[1] == mcversion]
  version = compat_versions[0]
  print u"Using Build", version
  filename = u"minecraftforge-universal-{0}-{1}.zip".format(mcversion, version)
  if use_mirror():
    fileurl = u"http://ken.wingedboot.com/forgemirror/files.minecraftforge.net/minecraftforge/" + filename
  else:
    fileurl = u"http://files.minecraftforge.net/minecraftforge/" + filename
  open(filename, u"wb").write(urllib2.urlopen(fileurl).read())
  return filename

def main():
  app = QApplication(sys.argv)
  ex = mainApp()
  sys.exit(app.exec_())

if __name__ == u'__main__':
  main()

 

Source (Python 3.x):

import sys
import os
import glob
import re
import urllib.request
import http.client as httplib
import shutil
import zipfile as z
from PySide.QtGui import *
from PySide.QtCore import *

class mainApp(QMainWindow):
  def __init__(self):
    super(mainApp, self).__init__()
    self.initUI()

  def initUI(self):
    self.mwidget = mainWidget()
    self.setCentralWidget(self.mwidget)
    status = self.statusBar()
    status.showMessage("Idle.")
    # Set the title
    self.setWindowTitle("Minecraft Forge Installer")
    self.resize(450, 180)
    self.show()

class mainWidget(QWidget):
  def __init__(self):
    super(mainWidget, self).__init__()
    self.initUI()

  def initUI(self):
    # Create widgets
    self.input_ent = QLineEdit(self)
    input_btn = QPushButton("Select minecraft.jar")
    input_btn.clicked.connect(self.getFile)
    self.minecraft_version_ent = QLineEdit(self)
    run_btn = QPushButton("Run")
    run_btn.clicked.connect(self.runEditMJar)
    # Create a layout
    vbox = QVBoxLayout()
    input_hbox = QHBoxLayout()
    input_hbox.addWidget(self.input_ent)
    input_hbox.addWidget(input_btn)
    vbox.addLayout(input_hbox)
    mversion_hbox = QHBoxLayout()
    mversion_hbox.addWidget(QLabel("Minecraft Version:"))
    mversion_hbox.addWidget(self.minecraft_version_ent)
    vbox.addLayout(mversion_hbox)
    vbox.addWidget(run_btn)
    # Show the window
    self.setLayout(vbox)
    self.show()

  def getFile(self):
    fname = QFileDialog.getOpenFileName(self, "minecraft.jar", ".", "Jar Files (*.jar)")[0]
    self.input_ent.clear()
    self.input_ent.insert(fname)

  def runEditMJar(self):
    fname = self.input_ent.displayText()
    version = self.minecraft_version_ent.displayText()
    if self.parentWidget().statusBar().currentMessage() == "Idle." and not os.path.exists("newzip"):
      self.sayWorking()
      QCoreApplication.processEvents()
      editJar(fname,version)
      self.sayDone()
    else:
      self.parentWidget().statusBar().showMessage("Action not allowed.", timeout=2000)

  def sayWorking(self):
    self.parentWidget().statusBar().showMessage("Editing Jar File.")

  def sayDone(self):
    self.parentWidget().statusBar().showMessage("Done.")

def editJar(filename, mcversion):
  original = z.ZipFile(filename)
  basename = os.path.basename(filename).split(".")[0]
  forge_name = download_forge(mcversion)
  forge = z.ZipFile(forge_name)
  os.makedirs("newzip")
  original.extractall(path="newzip")
  forge.extractall(path="newzip")
  original.close()
  forge.close()
  for delfile in glob.glob("newzip/META-INF/MOJANG*"):
    os.remove(delfile)
  shutil.make_archive(basename, "zip", "newzip")
  backup = os.path.dirname(filename) + "/backup.jar" 
  print("Backup: {0}, Filename: {1}".format(backup, filename))
  shutil.move(filename, backup)
  shutil.move(basename + ".zip", filename)
  shutil.rmtree("newzip")
  os.remove(forge_name)

def use_mirror():
  connection = httplib.HTTPConnection("files.minecraftforge.net", 80)
  connection.request("OPTIONS", "*")
  try:
    response = connection.getresponse()
    return False
  except:
    return True

def getversions(it):
  unp_versions = re.compile("Build [0-9].[0-9].[0-9].[0-9]*.*[0-9.]*").findall(it)
  p_versions = []
  for build in unp_versions:
    splitone = build.split(":")
    p_versions.append((splitone[0].split(" ")[1], splitone[-1][1:]))
  return p_versions

def download_forge(mcversion):
  using_mirror = use_mirror()
  if using_mirror:
    response = urllib.request.urlopen("http://ken.wingedboot.com/forgemirror/files.minecraftforge.net/").read()
  else:
    response = urllib.request.urlopen("http://files.minecraftforge.net/").read()
  versions = getversions(response.decode())
  if int(mcversion.replace(".","")) <= 132:
    exit()
  compat_versions = [i[0] for i in versions if i[1] == mcversion]
  version = compat_versions[0]
  print("Using Build", version)
  filename = "minecraftforge-universal-{0}-{1}.zip".format(mcversion, version)
  if use_mirror():
    fileurl = "http://ken.wingedboot.com/forgemirror/files.minecraftforge.net/minecraftforge/" + filename
  else:
    fileurl = "http://files.minecraftforge.net/minecraftforge/" + filename
  open(filename, "wb").write(urllib.request.urlopen(fileurl).read())
  return filename

def main():
  app = QApplication(sys.argv)
  ex = mainApp()
  sys.exit(app.exec_())

if __name__ == '__main__':
  main()

 

 

 

 

Binaries:

Linux- http://www.mediafire.com/?0358nmaz8dgmp (7z, tar.gz, tar.xz)

Windows Coming Soon

Posted

All in all this is rather useless and a pain for windows users as it requires python.

There is a plethroa of other tools out there for setting up your jars and the like.

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Consider supporting the team on Patreon

Posted

All in all this is rather useless and a pain for windows users as it requires python.

There is a plethroa of other tools out there for setting up your jars and the like.

That's why I'm trying to get it to work on windows (which it currently doesn't for some reason...) and then I'll use py2exe or pyinstaller to make an exe file which does not require python.

Posted

All in all this is rather useless and a pain for windows users as it requires python.

There is a plethroa of other tools out there for setting up your jars and the like.

I told him that...

Read the EAQ before posting! OR ELSE!

 

This isn't building better software, its trying to grab a place in the commit list of a highly visible github project.

 

www.forgeessentials.com

 

Don't PM me, I don't check this account unless I have to.

Guest
This topic is now closed to further replies.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Oh I forgot to update the title. I figured out the issue and I'm rather embarrassed to say that it was a file path issue. The game already knew I was accessing the achievements so I wasn't suppose to include advancements in the file path. Minecraft file paths have always confused me a little bit... ResourceLocation advancementId = new ResourceLocation( TheDeadRise.MODID,"adventure/spawntrigger");
    • Can someone help my with this? My forge server won't open and I'm not that good with this stuff. It gave me this error message:   C:\Users\apbeu\Desktop\Forge server>java -Xmx4G -Xms1G -jar server.jar nogui 2024-12-11 18:21:01,054 main WARN Advanced terminal features are not available in this environment [18:21:01] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher running: args [--gameDir, ., --launchTarget, fmlserver, --fml.forgeVersion, 36.2.34, --fml.mcpVersion, 20210115.111550, --fml.mcVersion, 1.16.5, --fml.forgeGroup, net.minecraftforge, nogui] [18:21:01] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher 8.1.3+8.1.3+main-8.1.x.c94d18ec starting: java version 21.0.4 by Oracle Corporation Exception in thread "main" java.lang.IllegalAccessError: class cpw.mods.modlauncher.SecureJarHandler (in unnamed module @0x402e37bc) cannot access class sun.security.util.ManifestEntryVerifier (in module java.base) because module java.base does not export sun.security.util to unnamed module @0x402e37bc         at cpw.mods.modlauncher.SecureJarHandler.lambda$static$1(SecureJarHandler.java:45)         at cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck(LamdbaExceptionUtils.java:95)         at cpw.mods.modlauncher.SecureJarHandler.<clinit>(SecureJarHandler.java:45)         at cpw.mods.modlauncher.Launcher.lambda$new$6(Launcher.java:55)         at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)         at cpw.mods.modlauncher.api.TypesafeMap.computeIfAbsent(TypesafeMap.java:52)         at cpw.mods.modlauncher.api.TypesafeMap.computeIfAbsent(TypesafeMap.java:47)         at cpw.mods.modlauncher.Environment.computePropertyIfAbsent(Environment.java:62)         at cpw.mods.modlauncher.Launcher.<init>(Launcher.java:55)         at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)         at net.minecraftforge.server.ServerMain$Runner.runLauncher(ServerMain.java:63)         at net.minecraftforge.server.ServerMain$Runner.access$100(ServerMain.java:60)         at net.minecraftforge.server.ServerMain.main(ServerMain.java:57) C:\Users\apbeu\Desktop\Forge server>pause
    • Here is the url for the crash report if anyone can help me, please. https://mclo.gs/KGn5LWy  
    • Every single time I try and open my modpack it crashes before the game fully opens and I don't know what is wrong. I open the crash logs but I don't understand what any of it means. What do I do?
    • Hey, sorry I haven't said anything in a while. I was banned on here for sending you straight up crash logs and they banned me for spam... but I learned that these forums are for forge only and I was working with neoforge... but thank you for all the help.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

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