| how to patch the game | |
|
|
Author | Message |
---|
tichfuie Super Contributor
Posts : 257 Join date : 2013-02-07 Location : NA
| Subject: how to patch the game Wed 10 Apr - 15:46 | |
| | |
|
| |
Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: how to patch the game Thu 11 Apr - 0:39 | |
| It is pretty simple to patch you need to have a webserver that allows people to download files. Then move the repositiory to a valid directory and run build_manifest.py (located in the respository directory) with the file path that you want to patch. It then goes through every file and creates a SHA-1 hash and stores it in the mv.patch file which the client downloads and compares to the local copy of the mv.patch.cur and sees which hashes do not match and downloads those files.
The c# client patch is a little more complicated but essential the same you just need to build the client (making some change to Multiverse.Patcher since it determines the patch num from that and if it is the same it wont patch everyone you might be able to override this) run build_patch_info.py from client/build directory which will package everything into a nice tar file that you can untar in an accessible folder. | |
|
| |
tichfuie Super Contributor
Posts : 257 Join date : 2013-02-07 Location : NA
| Subject: Re: how to patch the game Thu 11 Apr - 5:13 | |
| thanks delurin,
quick question:
is this documented on the wiki? cant seem to find references.
if not, I may try to add some info, but first need to learn how to :-) | |
|
| |
Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: how to patch the game Thu 11 Apr - 5:16 | |
| I am not sure what is in the wiki. | |
|
| |
tichfuie Super Contributor
Posts : 257 Join date : 2013-02-07 Location : NA
| Subject: Re: how to patch the game Fri 12 Apr - 13:00 | |
| @delurin
for some reason i cant find anywhere the build_manifest.py for the asset repository patch.
any way you can provide the script? | |
|
| |
Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: how to patch the game Fri 12 Apr - 14:09 | |
| Interestingly I dont see it on this computer. I will pull one tomorrow | |
|
| |
Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: how to patch the game Sat 13 Apr - 0:02 | |
| - Code:
-
#!/usr/bin/python
## This script will run through the world asset tree, and build a patch file based on the results import sha import time import re import sha import tarfile import zipfile import os.path import sys
class AssetTree: def __init__(self, clientDir, dstPath): # client dir is essentially the source directory self.client_dir = clientDir self.dst_path = dstPath self.dir_tree = {} self.manifest_entries = [] self.ignores = [] self.ignore_patterns = [] self.excludes = [] self.exclude_patterns = [] self.dir_pattern = re.compile(r'/')
def make_tar_file(self, tarfile_path): tar_file = tarfile.open(tarfile_path, "w") self.write_to_tar(tar_file) tar_file.close() def write_to_tar(self, tar_file): # add directories as versions of the MultiverseClient directory # this means that the permissions will be based on that tar_file.add(self.client_dir, self.dst_path, False) for entry in self.manifest_entries: tar_file.add(self.client_dir + entry.src_path, entry.dst_path, False) for subdir_name in self.dir_tree.keys(): self.dir_tree[subdir_name].write_to_tar(tar_file) def make_zip_file(self, zipfile_path): zip_file = zipfile.open(zipfile_path, "w") self.write_to_zip(zip_file) zip_file.close() def write_to_zip(self, zip_file): zip_info = zipfile.ZipInfo(self.dst_path) zip_info.external_attr = 16 # flag it as a directory zip_file.writestr(zip_info, '') for entry in self.manifest_entries: zip_file.write(self.client_dir + entry.src_path, entry.dst_path) for subdir_name in self.dir_tree.keys(): self.dir_tree[subdir_name].write_to_zip(zip_file)
# this should only be called on the root asset tree def add_asset_path(self, src_path, dst_path): # build a tree structure that will match our directory structure path_parts = self.dir_pattern.split(dst_path) self.add_asset(path_parts, src_path, dst_path)
def add_ignore(self, pattern): # build a tree structure that will match our directory structure self.ignores.append(pattern) self.ignore_patterns.append(re.compile(pattern))
def add_exclude(self, pattern): # build a tree structure that will match our directory structure self.excludes.append(pattern) self.exclude_patterns.append(re.compile(pattern))
def add_asset(self, pathParts, src_path, dst_path): if len(pathParts) == 1: if os.path.isdir(self.client_dir + src_path): if not self.dir_tree.has_key(pathParts[0]): self.dir_tree[pathParts[0]] = AssetTree(self.client_dir, self.dst_path + pathParts[0] + "/") elif os.path.isfile(self.client_dir + src_path): entry = ManifestEntry(src_path, dst_path, pathParts[0]) entry.compute_digest(self.client_dir) self.manifest_entries.append(entry) else: print "Invalid asset entry: " + self.client_dir + src_path elif len(pathParts) > 1: if not self.dir_tree.has_key(pathParts[0]): self.dir_tree[pathParts[0]] = AssetTree(self.client_dir, self.dst_path + pathParts[0] + "/") self.dir_tree[pathParts[0]].add_asset(pathParts[1:], src_path, dst_path)
def add_asset_helper(self, src_dir): for entry in os.listdir(self.client_dir + src_dir): src_path = src_dir + entry ignore = False # check to see if we should skip this for pattern in self.ignore_patterns: match = pattern.match(src_path) if match and match.end(0) == len(src_path): ignore = True # ignore this entry, but still recurse break for pattern in self.exclude_patterns: match = pattern.match(src_path) if match and match.end(0) == len(src_path): # ignore this entry, and do not recurse return # ok, we don't ignore this.. if os.path.isdir(self.client_dir + src_path): if not ignore: self.add_asset_path(src_path, src_path) self.add_asset_helper(src_path + "/") elif os.path.isfile(self.client_dir + src_path): if not ignore: self.add_asset_path(src_path, src_path) else: print "Invalid asset entry: " + self.client_dir + src_path def print_all_entries(self, f, rev, url): f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") f.write("<patch_data revision=\"%s\" url=\"%s\">\n" % (rev, url)) for entry in self.excludes: f.write(" <exclude pattern=\"%s\"/>\n" % entry) for entry in self.ignores: f.write(" <ignore pattern=\"%s\"/>\n" % entry) self.print_entries(f, "") f.write("</patch_data>\n")
def print_entries(self, f, dir_name): for subdir_name in self.dir_tree.keys(): f.write(" <entry name=\"%s\" kind=\"dir\" />\n" % (dir_name + subdir_name)) for entry in self.manifest_entries: f.write(" <entry name=\"%s%s\"\n" % (dir_name, entry.fileName)) f.write(" kind=\"file\" sha1_digest=\"%s\" size=\"%d\" />\n" % (entry.sha1Digest, entry.contentLength)) for subdir_name in self.dir_tree.keys(): self.dir_tree[subdir_name].print_entries(f, dir_name + subdir_name + "/")
class ManifestEntry: def __init__(self, src_path, dst_path, fileName): # src_path is the path of the source file relative to the client_dir self.src_path = src_path # dst_path is the path of the file relative to the install dir self.dst_path = dst_path # fileName is the last component of the path to which we install self.fileName = fileName self.sha1Digest = "" self.contentLength = 0
def compute_digest(self, client_dir): md = sha.new() filename = client_dir + self.src_path f = file(filename, "rb") f.seek(0, 2) size = f.tell() f.seek(0, 0) while 1: data = f.read(4096) if len(data) == 0: break md.update(data) f.close() self.contentLength = size self.sha1Digest = md.hexdigest()
def add_assets(asset_tree): # the manifest file (and room for the local copy) asset_tree.add_ignore("mv.patch") asset_tree.add_ignore("mv.patch.cur") # in case they run the script from the assets dir asset_tree.add_ignore("build_manifest.py") # in case they run from a subversion checked out tree asset_tree.add_ignore("(.*/)?\.svn(/.*)?") # in case they run from a windows system where they get Thumbs.db asset_tree.add_ignore("(.*/)?Thumbs.db") # the client shouldn't get the asset definitions asset_tree.add_ignore("AssetDefinitions(/.*)?") #Comment out for distributing world building asset definitions # the client shouldn't get the assetlist files asset_tree.add_ignore(".*\.assetlist") asset_tree.add_ignore(".*\..*~") asset_tree.add_ignore(".*#.*#") # the various files in the addons directories asset_tree.add_ignore("AddOns/Fonts/.*") asset_tree.add_ignore("AddOns/GpuPrograms/.*") asset_tree.add_ignore("AddOns/Icons/.*") asset_tree.add_ignore("AddOns/Imagefiles/.*") asset_tree.add_ignore("AddOns/Interface/Imagesets/.*") asset_tree.add_ignore("AddOns/Interface/FrameXML/.*") asset_tree.add_ignore("AddOns/Materials/.*") asset_tree.add_ignore("AddOns/Meshes/.*") asset_tree.add_ignore("AddOns/Scripts/.*") asset_tree.add_ignore("AddOns/Skeletons/.*") asset_tree.add_ignore("AddOns/Sounds/.*") asset_tree.add_ignore("AddOns/SpeedTree/.*") asset_tree.add_ignore("AddOns/Textures/.*") asset_tree.add_ignore("AddOns/Physics/.*")
asset_tree.add_asset_helper("") def get_release(): return "0.8.%d" % time.time()
if len(sys.argv) == 1: print "Usage: %s <path_to_world_assets> [<update_url> [<version_number>]]" % sys.argv[0] exit
world_asset_path = "" update_url = "http://update.multiverse.net/mvupdate.media/" version = get_release()
world_asset_path = sys.argv[1] if len(sys.argv) >= 3: update_url = sys.argv[2] if len(sys.argv) >= 4: version = sys.argv[3]
if not world_asset_path.endswith('/'): world_asset_path = world_asset_path + '/'
f = file(world_asset_path + "mv.patch", "w") asset_tree = AssetTree(world_asset_path, "") add_assets(asset_tree) asset_tree.print_all_entries(f, version, update_url) f.close() | |
|
| |
tichfuie Super Contributor
Posts : 257 Join date : 2013-02-07 Location : NA
| Subject: Re: how to patch the game Sat 13 Apr - 6:36 | |
| thanks delurin, well, i created the patch file uploaded assets to my local web server, changed all patcher/update links from C# client point to my local web server try to run the client and no client runs at all. client runs fine if i add the --noupdate deal tho so client should work ok. then look at my logs and all i see is: - Quote :
INFO [2013-04-12 14:25:13,494] MultiverseClient Client command line arguments: INFO [2013-04-12 14:25:13,504] MultiverseClient Checking if restart required INFO [2013-04-12 14:25:13,506] MultiverseClient Checking for client updates at URL 'http://127.0.0.1/mv/update/patch_version.txt' INFO [2013-04-12 14:25:13,541] MultiverseClient Patching from 0.8.1365785377 to 0.8.1365785378 INFO [2013-04-12 14:25:13,541] MultiverseClient Downloading patcher... INFO [2013-04-12 14:25:13,541] MultiverseClient Restart required INFO [2013-04-12 14:25:13,541] MultiverseClient Cleaning up INFO [2013-04-12 14:25:13,541] MultiverseClient Exiting Client
but nothing happens on my end. it does not download anything , logs show restarting client but nothing happens. any idea on whats going on? | |
|
| |
Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: how to patch the game Sat 13 Apr - 12:15 | |
| It looks like it is trying to patch the game client (the file I posted was to patch the media assets not the client) I believe there is a command to update the assets and not the game but I dont remember it off the top of my head.
You may need to run it as administrator to patch the game client. I dont remember how but I modified the patcher to automatically elevate when it needed to patch. Probably one of the coolest things Ive done since it only does it when it needs to unlike most AAA mmos. | |
|
| |
tichfuie Super Contributor
Posts : 257 Join date : 2013-02-07 Location : NA
| Subject: Re: how to patch the game Sat 13 Apr - 13:35 | |
| running it as administrator did not work either.
one more to the naughty list of MV.
anyways, i was planing to pack encrypt the clients assets and the existing patcher is per file only, and i needed a binary patcher that will patch only the binary difference.
| |
|
| |
AthlonJedi Administrator
Posts : 213 Join date : 2012-07-19 Location : Walkerton, Indiana
| Subject: Re: how to patch the game Mon 15 Apr - 1:28 | |
| Welcome to the incomplete mess that is multiverse. this isnt the only thing that needs alot of work but I do give the foundation credit for taking this on. Now if we could just get them to stop pissing around with win XP ( i mean really? no one i know runs production level servers on xp ) and update a few things this system DOES have potential.
Im even thinking about giving it a 3000th try!
But on a serious note, I dont remember setting up the patching system to be all that hard, I believe all you need is a http server with client download permissions availible.
| |
|
| |
tichfuie Super Contributor
Posts : 257 Join date : 2013-02-07 Location : NA
| Subject: Re: how to patch the game Mon 15 Apr - 2:21 | |
| lol, yeah, the more you dig in the more dirt you find.
but regarding XP for production, i dont think this is entirely the case.
the server runs on my win7 64 without any issue. aswell as in my centOS 5.8 box.
well it is java, so java can run in pretty much any system so i dont think it is tied up to XP only, i assume that was because that was what was being used back then. | |
|
| |
AthlonJedi Administrator
Posts : 213 Join date : 2012-07-19 Location : Walkerton, Indiana
| Subject: Re: how to patch the game Mon 15 Apr - 2:29 | |
| Granted, however, the whole windows xp / server 2000 support chain has ended long ago, as such, it would be a good Idea to update everything to a vista / server 2008 support chain. I understand the desire to support older systems, however, there is a point when you have to cut support for old technologies in favor of current/future ones. | |
|
| |
Sponsored content
| Subject: Re: how to patch the game | |
| |
|
| |
| how to patch the game | |
|