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



×
×
  • Create New...

Important Information

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