菜单

SMCL – 使用Python编写简单Minecraft启动器

2016年4月4日 - Linux & homelab

Simple Minecraft Launcher,一个使用python3编写的轻量级Minecraft启动器。

代码见:http://ideone.com/aVWnVh , Github地址:https://github.com/WuSiYu/smcl。直接不加任何参数运行脚本会显示帮助和用法,这里就不再多说了。

 

下面介绍原理:

其实Minecraft这个东西,是可以用一句命令直接启动的。但由于java的尿性,-cp=”xxxx.jar:xxxxx.jar”这个加载用到的库的参数会非常的长,再加上Minecraft本身又有一堆参数,所以这个“一句命令”虽说是一句,却有一千多个字符长。。。

所以就有了启动器这么个玩意,说白了它的功能就是生成启动命令,然后执行它。

听起来虽然蛋疼,不过好在Minecraft的每个版本都会有一个json文件,里面详细的写明了用到的库、asset名、参数、主类等信息,只有解析它即可,并不复杂。

而关于盗版的问题,只要将参数中的user_type设置为Legacy即可直接跳过验证来启动,这大概是游戏界最简单的“破解”了吧。其实这是Mojang并不特别反对盗版的原因,要不然也不会这么轻松。

反正要是有钱还是都去买个正版吧,这么良心的游戏不多了。(某穷b说道。。。)

 

—– 2016-04-30 更新 —–

详细用法:

首先,这是一个命令行程序,没有界面的。而且需要命令行参数来用。

如果没有任何参数输入,则会显示帮助信息并退出。

下面是命令行参数的详细说明,python命令和脚本名视情况而定:

基本用法:
python3 SMCL.py [-d minecraft所在目录] [-v 要启动的版本] [-m JAVA最大内存] 你的游戏ID

前三项可选,实际使用时去掉括号。游戏ID是必须的,如果没有写则不能启动。

如果minecraft所在目录未指定,则使用当前目录下的.minecraft目录

如果要启动的版本未指定,则会启动minecraft目录中最新的那个版本

如果最大内存未指定,则会设置为2048m,也就是2G

下面是一些栗子:

游戏ID:WuSiYu, minecraft目录为当前目录下的.minecraft目录(默认值),启动minecraft目录中最新的那个版本(默认值), JAVA最大内存为2G(默认值):

python3 SMCL.py WuSiYu

 

游戏ID:WuSiYu, minecraft目录为当前目录(将脚本放到.minecraft目录里时用这个),启动minecraft目录中最新的那个版本(默认值), JAVA最大内存为2G(默认值):

python3 SMCL.py -d . WuSiYu

 

游戏ID:WuSiYu, minecraft目录为当前目录(将脚本放到.minecraft目录里时用这个), 启动1.7.10版本,JAVA最大内存为2G(默认值):

python3 SMCL.py -d . -v 1.7.10 WuSiYu

 

游戏ID:WuSiYu, minecraft目录为当前目录(将脚本放到.minecraft目录里时用这个), 启动1.7.10版本,JAVA最大内存为8G(也就是8192m):

python3 SMCL.py -d . -v 1.7.10 -m 8192m WuSiYu

 

PS:我现在还在继续编写这个启动器,预计会加入下载等功能

—– 16-04-30 更新结束 —–

 

下面附上完整代码:

#!/usr/bin/python3
import os, json, sys

# default value
MinecraftDir = './.minecraft'
Version = ''
maxMen = '2048m'
ID = ''

# get jar files path from the json file
def getJars(minecraftDir, version):
    jsonFilePath = minecraftDir+'/versions/'+version+'/'+version+'.json'

    with open(jsonFilePath, 'r') as jsonFile :
        jsonFileContent = jsonFile.read()

    jsonFileKeys = json.loads( jsonFileContent )

    jars = ''
    for x in jsonFileKeys['libraries']:
        jarFileParts = x['name'].split(':')
        jarFile =    MinecraftDir+'/libraries/' + \
                    jarFileParts[0].replace('.','/')+'/'+jarFileParts[1] +'/'+jarFileParts[2] + '/' + \
                    jarFileParts[1]+'-'+jarFileParts[2]+'.jar'

        jars += jarFile+':'
    
    if 'inheritsFrom' in jsonFileKeys.keys():
        jars += getJars(minecraftDir, jsonFileKeys['inheritsFrom'])

    return jars

# generate the Minecraft Argvs from the json file
def getMinecraftArgvs(minecraftDir, version, ID):
    jsonFilePath = minecraftDir+'/versions/'+version+'/'+version+'.json'
    with open(jsonFilePath, 'r') as jsonFile :
        jsonFileContent = jsonFile.read()

    jsonFileKeys = json.loads( jsonFileContent )
    argvs = jsonFileKeys['minecraftArguments']
    argvs = argvs    .replace('${auth_player_name}', ID)\
                    .replace('${version_name}', '{}')\
                    .replace('${game_directory}', minecraftDir)\
                    .replace('${assets_root}', minecraftDir+'/assets')\
                    .replace('${assets_index_name}', jsonFileKeys['assets'])\
                    .replace('${auth_uuid}', '{}')\
                    .replace('${auth_access_token}', '{}')\
                    .replace('${user_type}', 'Legacy')\
                    .replace('${version_type}', jsonFileKeys['type'])\
                    .replace('${user_properties}', '{}')
    argvs = jsonFileKeys['mainClass'] + ' ' + argvs
    return argvs


# process argvs for this script
job = 0
theUsageText = 'Usage:\t\t'+sys.argv[0]+' [-d Minecraft_dir] [-v version] [-m 2048m] Username\n\t\t\tLaunch Minecraft\n\n\t\t'+sys.argv[0]+' [-d Minecraft_dir] -l\n\t\t\tList Minecraft versions'

if len(sys.argv) == 1:
    print(theUsageText)
    sys.exit()
else:
    t=1
    while t<len(sys.argv):
        if sys.argv[t] == '-d':
            t+=1
            MinecraftDir = sys.argv[t]
        elif sys.argv[t] == '-v':
            t+=1
            Version = sys.argv[t]
        elif sys.argv[t] == '-m':
            t+=1
            maxMen = sys.argv[t]
        elif sys.argv[t] == '-h':
            print(theUsageText)
            sys.exit()
        elif sys.argv[t] == '-l':
            job = 1
        else:
            ID = sys.argv[t]

        t+=1

if job == 1:        #if the job is list Minecraft versions, do it and exit
    print('Minecraft versions:')
    versions = os.listdir(MinecraftDir+'/versions/')
    versions.sort(reverse=True)
    for x in versions:
        print( '\t'+x )
    sys.exit()

if ID == '':        #if do not specify a ID, print the usage and exit
    print(theUsageText)
    sys.exit()

if Version == '':    #if do not specify a version, set the Version value to the latest version
    versions = os.listdir(MinecraftDir+'/versions/')
    versions.sort(reverse=True)
    Version = versions[0]
# end of this part


# generate command to launch Minecraft
befour = 'java -Xincgc -XX:-UseAdaptiveSizePolicy -XX:-OmitStackTraceInFastThrow -Xmn128m -Xmx'+maxMen+' -Djava.library.path='+MinecraftDir+'/versions/'+Version+'/'+Version+'-natives -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true -Duser.home=/ -cp "'

after = getMinecraftArgvs(MinecraftDir, Version ,ID)

jars = getJars(MinecraftDir, Version)
jars += MinecraftDir+'/versions/'+Version+'/'+Version+'.jar" '

cmd = befour + jars + after
# end of this part


# launch Minecraft
os.system(cmd)
0

SMCL – 使用Python编写简单Minecraft启动器》有15个想法

zengda

不错,不错,看看了!

0
回复
弹霄博科

不错啊,也欢迎把代码放到Coding(https://coding.net/register?key=119123f2-cfc6-4c00-9277-7dc1bff962ed) 上来

0
回复
    弹霄博科

    好明显的推荐,2333

    0
    回复
MINECRAFT

如果可以有更详细的教学就好了><

0
回复
MINECRAFT

要怎么样运行呢><

0
回复
    WuSiYu

    把代码存为.py文件,然后在终端里用python运行它就可以了。
    命令行参数会提示的。

    其实这个启动器的功能十分简单,仅仅是能启动Minecraft。写这个的目的其实主要是为了给做服里的专用客户端做准备。
    要是日常使用,我还是推荐使用HMCL这种比较成熟的启动器。

    0
    回复
      MINECRAFT

      谢谢回复,but出现了些问题
      1. 该代码已存档成 .py文件
      2. .minecraft的文件也放在同一个文件夹里面
      3. 也已添加用户名和Version

      运行时,cmd 出现
      [-d Minecraft_dir] [-v version] [-m 2048m] Username
      Launch Minecraft
      [-d Minecraft_dir]
      List Minecraft versions

      请问程式中的那一部分还需要进行修改的呢><

      0
      回复
        WuSiYu

        输出这个是正常的。
        这是一个命令行程序,需要通过命令行参数来运行。
        如果没有参数输入,则会输出帮助信息。

        正确的使用方法是:python3 xxxx.py -v 要启动的版本 -d minecraft的目录 -m 最大的内存 你的ID

        前3个参数是可选的,而ID是必须的。

        更详细的说明等我更新一下文章

        PS:抱歉这么晚才看到

        0
        回复
        WuSiYu

        文章已添加更详细的使用方法

        0
        回复
          MINECRAFT

          没关系没关系, 谢谢你的耐心回复喔

          明天我晚上试看看

          我会继续一直关注你的BLOG的,加油!

          0
          回复
      January

      Volkswagen is a good brand and Jetta is a good model. Go for it if you do2&8#n17;t mind its look because many people don’t like it. Many friends of mine who own Jetta from 1998 model to latest model, no one has any complaint so far.

      0
      回复
静静

我只想知道你用的这个光影是什么

0
回复
    WuSiYu

    自己改了一些的KUDA 5.06

    0
    回复
CarnivioN

请教一下,java的参数我不是很懂,-Xincgc是什么意思呢?我运行的时候说“Unrecognized option: -Xincgc”

0
回复
    WuSiYu

    打开增量式GC,以减少GC开销
    加不加应该都是可以的

    0
    回复

zengda进行回复 取消回复

电子邮件地址不会被公开。 必填项已用*标注