Skip to content
This repository was archived by the owner on Nov 9, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
e58455a
Adds savedata to the Research folder for testing.
unixtreme Nov 14, 2018
fe8ffeb
Implements save manager to handle Save Data.
unixtreme Nov 16, 2018
6aee72e
Resolves conflict with upstream.
unixtreme Nov 17, 2018
2356aaf
Resolves conflict with upstream.
unixtreme Nov 17, 2018
78b9aac
Adds basic framework for GUI feature and GUI branch.
unixtreme Nov 17, 2018
a51a209
Resolves bug with hero importing.
unixtreme Nov 18, 2018
65b1748
Resolves bug with hero importing.
unixtreme Nov 18, 2018
1cbe708
Initial GUI commit.
unixtreme Nov 19, 2018
f9c18a2
Merge remote-tracking branch 'origin/master'
unixtreme Nov 19, 2018
2909838
Implements basic GUI for materials.
unixtreme Nov 19, 2018
f0eb602
Adds error message if protobuf is missing.
unixtreme Nov 19, 2018
0a72a18
Implements GUI for HC materials
unixtreme Nov 20, 2018
a7faebd
Implements paragon levels on GUI for HC and SC
unixtreme Nov 20, 2018
d2abf4f
General style changes for PEP8 compliance.
unixtreme Nov 20, 2018
b981f4a
FIX: Actually save changes to Paragon level.
unixtreme Nov 20, 2018
a7bf872
Remember window location, set starting window size.
unixtreme Nov 20, 2018
324ce84
Creating tabs for account and so on.
unixtreme Nov 20, 2018
12315aa
Populates hero tab with currently loaded heroes.
unixtreme Nov 21, 2018
b5ebfc9
Adds some information into the hero frames of the hero_tab.
unixtreme Nov 21, 2018
bb4f222
Adds Stash tab.
unixtreme Nov 21, 2018
72cfc53
Allows to save Hero changes.
unixtreme Nov 21, 2018
c3af8c8
Allows to save Hero changes.
unixtreme Nov 21, 2018
74256b3
Merge remote-tracking branch 'origin/master'
unixtreme Nov 21, 2018
cd80b4e
Dummy commit for stash manager
unixtreme Nov 21, 2018
bef7292
Fix: Save Hero button disappearing after changing hero.
unixtreme Nov 21, 2018
5f809ea
Fix: Paragon level should now take effect.
unixtreme Nov 22, 2018
13ec77c
Basic inventory read only view.
unixtreme Nov 22, 2018
f143913
Translates some item name labels.
unixtreme Nov 22, 2018
2603cdd
Basic item and affix decoding
unixtreme Nov 23, 2018
db33850
Basic item and affix decoding
unixtreme Nov 23, 2018
9aa8e8a
Adds Hero inventory listing. Includes categorised gbid_list for futur…
unixtreme Nov 23, 2018
2faaa82
Hero item decoding (for now on stash tab)
unixtreme Nov 23, 2018
bd93984
fix to silly missing parenthesis.
unixtreme Nov 23, 2018
dd841c0
Adds GR keystone to gbids
unixtreme Nov 26, 2018
bebdae6
Inserts effectiveness values into affix effects for the GUI.
unixtreme Nov 26, 2018
be88392
Small refactor to de-clutter project main folder.
unixtreme Nov 26, 2018
99f15a4
Small refactor to de-clutter project main folder.
unixtreme Nov 26, 2018
ed9b090
Adds linux/darwin venv with dependencies
unixtreme Nov 26, 2018
ba58209
Adds Windows venv with dependencies
unixtreme Nov 26, 2018
f9202de
Updated Readme with instructions for GUI.
unixtreme Nov 26, 2018
121075e
Adding VisualStudio to Credits as he is working on doing this on C++/C#
unixtreme Nov 26, 2018
b9eac5b
Update README.md
unixtreme Nov 26, 2018
411be48
Adding gbid number to the Unknown Item and Unknown Affix strings
unixtreme Nov 26, 2018
cb77262
Reverting modded_ hero renaming for simplicity of use.
unixtreme Nov 26, 2018
6612e55
Adds option to edit currencies on Season.
unixtreme Nov 27, 2018
24d5bf8
Possible fix for level edition.
unixtreme Nov 28, 2018
d75101c
Removing bat file as it's inconsistent and I don't want to debug it.
unixtreme Nov 28, 2018
5681b37
Removing bat file as it's inconsistent and I don't want to debug it.
unixtreme Nov 28, 2018
032e121
Hotfixing cases of corruption on plvl changes.
unixtreme Nov 28, 2018
d21d234
Initial item edit feature.
unixtreme Nov 29, 2018
f360f34
Merge pull request #1 from unixtreme/itemedit
unixtreme Nov 29, 2018
450c588
Removing CLI options as they are obsolete.
unixtreme Nov 30, 2018
02c0da8
Removing Research folder to keep project tidy
unixtreme Nov 30, 2018
ab5dc6e
Merge branch 'master' into itemedit
unixtreme Nov 30, 2018
3886a6a
Moving affixes and currencies to a database.
unixtreme Nov 30, 2018
da16a88
Merge pull request #2 from unixtreme/itemedit
unixtreme Nov 30, 2018
f27e3df
moving gbids to database.
unixtreme Nov 30, 2018
8332697
Merge pull request #3 from unixtreme/itemedit
unixtreme Nov 30, 2018
736a1b9
Update README.md
unixtreme Nov 30, 2018
a29d7d9
Adds Gem Edition
unixtreme Dec 2, 2018
bd24225
Moving rift level to account (rightful place), edition not working.
unixtreme Dec 3, 2018
be0d745
Rift edition may work.
unixtreme Dec 3, 2018
ccad028
Adds some items to DB. Adds slot identification. Adds ability to modi…
unixtreme Dec 6, 2018
f7ac746
Fix for accounts with no gr levels cleared.
unixtreme Dec 6, 2018
4e15323
Commenting out highest GR for now, it may need to be added back as we…
unixtreme Dec 10, 2018
30fbdd2
Commenting out highest GR for now, it may need to be added back as we…
unixtreme Dec 10, 2018
4ec50f8
Merge remote-tracking branch 'origin/master'
unixtreme Dec 10, 2018
fa5b615
Prototype for adding items (by ID, very generic)
unixtreme Dec 10, 2018
47863a5
Fixes an issue editing certain affixes. Affix dropdown auto-resizes.
unixtreme Dec 11, 2018
1eae81b
Fixes an issue with saving items. Adds "Safe Mode" for edition (Work …
unixtreme Dec 12, 2018
43066d1
DB update.
unixtreme Dec 12, 2018
6b3bed6
Update README.md
unixtreme Dec 12, 2018
75c8f09
Update README.md
unixtreme Dec 12, 2018
c4ebfe5
Update README.md
unixtreme Dec 12, 2018
0002c45
Deleting items is now possible (with safemode off).
unixtreme Dec 12, 2018
6d1657c
Added ids to item names for easy item adding. Item name label can now…
unixtreme Dec 12, 2018
aa7aeca
Small aesthetic change for item names in scrollbar.
unixtreme Dec 12, 2018
603631a
Safe Mode database updated.
unixtreme Dec 12, 2018
21f60fd
minor item naming changes
unixtreme Dec 12, 2018
8097ca7
Minor GUI improvements
unixtreme Dec 12, 2018
f20b2e7
Minor GUI improvements (2)
unixtreme Dec 12, 2018
d15c104
Added gems and affixes to DB
unixtreme Dec 13, 2018
f70c2eb
Added gems and affixes to DB
unixtreme Dec 13, 2018
4e9b072
adding script for macos
unixtreme Dec 14, 2018
1cf0920
Improving autoresize for affixes window.
unixtreme Dec 14, 2018
2f0c064
Adding clone item and reroll item options.
unixtreme Dec 17, 2018
0b731ce
Adding search filter for affixes.
unixtreme Dec 17, 2018
403f1e9
Added some definitions for safe mode.
unixtreme Dec 17, 2018
38c54db
Added more items to DB. Most items are categorised.
unixtreme Dec 28, 2018
d246f82
Added more items to DB. Most items are categorised.
unixtreme Dec 28, 2018
49450b5
Can specify quality when adding items.
unixtreme Dec 28, 2018
05f8d8e
Can specify quality when adding items.
unixtreme Dec 29, 2018
98a85a7
Basic item browser for Add Item.
unixtreme Jan 10, 2019
7c2d33e
Set to Primal and adjusted width
TheSixWings Jul 9, 2019
7cd824f
Right Aligned Currency Label
TheSixWings Jul 10, 2019
480507b
UI modified Account & Heroes Tabs
TheSixWings Jul 10, 2019
bc94701
UI modified Stash Tabs
TheSixWings Jul 11, 2019
028d058
Add LabelMessage
TheSixWings Jul 11, 2019
2f0cda7
UI Fix: AddItemFrame
TheSixWings Jul 11, 2019
1fc1194
UI Fix: ButtonFrame
TheSixWings Jul 11, 2019
e00905e
UI Modified: Listbox & Scrollbar
TheSixWings Jul 11, 2019
cb967eb
Update README.md
TheSixWings Jul 11, 2019
a2ab87b
Update README.md
TheSixWings Jul 11, 2019
edb7077
Duplicate Item Auto Reroll seed
TheSixWings Jul 13, 2019
201cc85
Merge branch 'Primal' of https://github.com/super1tman/D3Edit into Pr…
TheSixWings Jul 13, 2019
3e3660c
Revert "Merge branch 'Primal' of https://github.com/super1tman/D3Edit…
TheSixWings Jul 13, 2019
68000df
Remark Filter
TheSixWings Jul 14, 2019
e9d1707
Wizard^Pants
TheSixWings Jul 14, 2019
9d6d6bf
Wizard^Ring
TheSixWings Jul 14, 2019
1746db7
Wizard^Helm/Wizard Hat
TheSixWings Jul 15, 2019
9b8cdb2
Wizard^Shoulders
TheSixWings Jul 15, 2019
83305e6
Wizard^Amulet
TheSixWings Jul 15, 2019
2175347
Wizard^Chest Armor
TheSixWings Jul 16, 2019
8960831
Wizard^Belt
TheSixWings Jul 16, 2019
4df6026
Wizard^Gloves
TheSixWings Jul 16, 2019
30603e4
Wizard^Bracers/Boots
TheSixWings Jul 16, 2019
a5dd549
Wizard^Axe/Mace/Spear/Sword/Wand
TheSixWings Jul 17, 2019
619bc3a
Wizard^Two-Handed Axe/Two-Handed Mace/Staff/Two-Handed Sword/Bow/Cros…
TheSixWings Jul 20, 2019
f9c01ed
Wizard^Shield
TheSixWings Jul 20, 2019
a0d15e9
Wizard^Source
TheSixWings Jul 20, 2019
c118821
Add more filter
TheSixWings Jul 20, 2019
9177dc9
Bug Fix
TheSixWings Jul 20, 2019
fd971ed
Duplicate Gem
TheSixWings Jul 21, 2019
991280d
Merge pull request #6 from TheSixWings/Primal
unixtreme Jun 9, 2021
fb76a5a
Update Readme.md credits.
unixtreme Jun 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.pyc
*.lnk
* - Copy.*
155 changes: 19 additions & 136 deletions D3Edit.py
Original file line number Diff line number Diff line change
@@ -1,143 +1,26 @@
#!/usr/bin/env python3

from json import load
from sys import getsizeof
from os.path import isfile, join
from argparse import ArgumentParser
from binascii import hexlify as _hexlify
import platform
from os import getcwd

# pip3 install protobuf
import Account_pb2

BYTE_MAX_VALUE = 255
XOR_KEY = 0x305F92D82EC9A01B
def main():
import gui
# Initialize GUI
instanced_gui = gui.D3Edit()
instanced_gui.start()

GBIDS_FILE = "gbids.json"
SLOTS_FILE = "slots.json"
AFFIXES_FILE = "affixes.json"
CURRENCY_FILE = "currencies.json"

HERO_DIR = "heroes"
ASSET_DIR = "assets"

def hexlify(b: (bytes, bytearray)) -> (bytes, bytearray):
"""
bytes -> hex
:param b: the bytes you want to convert to hex
:return: the hex string representation of the specified bytes
"""
return _hexlify(b).decode("utf8")

def truncate(num: int, boundary: int, signed: bool, endian: str = "little") -> int:
"""
Truncate an int to a given byte boundary
:param num: the number to truncate
:param margin: the byte boundary
:param signed: whether or not the int is signed
:param endian: the integer's endianness
:return: the truncated integer
"""
return int.from_bytes(num.to_bytes(getsizeof(num), endian, signed=signed)[:boundary], endian, signed=signed)

def decrypt_save(data: (bytes, bytearray)) -> (bytes, bytearray):
"""
Decrypt a save file
:param data: the save data to decrypt
:return: the decrypted save data
"""
global XOR_KEY

if isinstance(data, bytes):
data = bytearray(data)

num = XOR_KEY
for i in range(len(data)):
data[i] ^= (num & BYTE_MAX_VALUE)
num = truncate((((num ^ data[i]) << 56) | num >> 8), 8, False)

return bytes(data)

def encrypt_save(data: (bytes, bytearray)) -> (bytes, bytearray):
"""
Encrypt a save file
:param data: the save data to encrypt
:return: the encrypted save data
"""
global XOR_KEY

if isinstance(data, bytes):
data = bytearray(data)

num1 = XOR_KEY
for i in range(len(data)):
num2 = data[i]
data[i] ^= (num1 & BYTE_MAX_VALUE)
num1 = truncate(((num1 ^ num2) << 56) | num1 >> 8, 8, False)

return bytes(data)

if __name__ == "__main__":
# make sure assets exist
assert isfile(join(ASSET_DIR, GBIDS_FILE)), "%s doesn't exist" % (GBIDS_FILE)
assert isfile(join(ASSET_DIR, AFFIXES_FILE)), "%s doesn't exist" % (AFFIXES_FILE)
assert isfile(join(ASSET_DIR, CURRENCY_FILE)), "%s doesn't exist" % (CURRENCY_FILE)

# load assets
with open(join(ASSET_DIR, GBIDS_FILE), "r") as f:
gbid_list = load(f)
with open(join(ASSET_DIR, AFFIXES_FILE), "r") as f:
affix_list = load(f)
with open(join(ASSET_DIR, CURRENCY_FILE), "r") as f:
currency_list = load(f)
with open(join(ASSET_DIR, SLOTS_FILE), "r") as f:
slot_list = load(f)

# parse arguments
parser = ArgumentParser(description="A script to encrypt/decrypt and modify Diablo III saves")
parser.add_argument("-i", "--in-file", type=str, required=True, help="The account file you want to work with")
parser.add_argument("-o", "--out-file", type=str, default="account_modified.dat", help="The account file you want to output to")
select_group = parser.add_argument_group("selection")
select_group.add_argument("-s", "--slot", type=int, default=0, help="The slot ID you want to work with")
mod_group = parser.add_argument_group("modifications")
for single in currency_list:
mod_group.add_argument("--" + single.lower().replace("'", "").replace(" ", "-"), type=int, help="Set the amount of %s" % (single.lower()))
mod_group.add_argument("--all-currencies", type=int, help="Set all currencies to the given value")
args = parser.parse_args()

# make sure the input file exists
assert isfile(args.in_file), "input file doesn't exist"

# account
# decrypt
with open(args.in_file, "rb") as f:
account_enc = f.read()
account_dec = decrypt_save(account_enc)

# parse
asd = Account_pb2.SavedDefinition()
asd.ParseFromString(account_dec)

# modify account here
if len(asd.partitions[args.slot].currency_data.currency) > 0:
for currency_id in range(len(currency_list)):
currency_name = currency_list[currency_id]
if len(asd.partitions[args.slot].currency_data.currency) >= (currency_id + 1):
amt = None
try:
amt = getattr(args, currency_name.lower().replace("'", "").replace(" ", "_"))
if not amt and args.all_currencies:
amt = args.all_currencies
except AttributeError:
pass
if amt:
print("Set slot %s %s to %s" % (args.slot, currency_name.lower(), amt))
asd.partitions[args.slot].currency_data.currency[currency_id].count = amt

# end account modifications
account_mod_dec = asd.SerializeToString()
account_mod_enc = encrypt_save(account_mod_dec)
# output the modified account
if args.out_file:
with open(args.out_file, "wb") as f:
f.write(account_mod_enc)
# end account output
venv_platforms = ['Linux', 'Darwin']
running_os = platform.system()
# activate Linux/Darwin venvs:
if any(p in running_os for p in venv_platforms):
print("activated linux venv")
activate_this_file = "{}/venv/bin/activate_this.py".format(getcwd())
exec(open(activate_this_file).read(), dict(__file__=activate_this_file))
elif running_os == 'Windows':
print("Activating Windows venv")
activate_this_file = "{}\\winvenv\\Scripts\\activate_this.py".format(getcwd())
exec(open(activate_this_file).read(), dict(__file__=activate_this_file))
main()
103 changes: 22 additions & 81 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,90 +1,31 @@
### A script to encrypt/decrypt and modify Diablo III saves
### A program to encrypt/decrypt and modify Diablo III saves
Instructions:
- Make sure Python3 is installed.
- Run D3Edit.py with python3.

This script is a WIP for modifying Xbox One, PS4, and Switch saves for Diablo III
Currently supported:

- Currency edition.
- Hero and account edition: Hero level, Paragon level, Highest GR completed...
- Stash and Hero inventory viewing.
- Item edition.
- Item generation (By ID).

An example of how to mod gold would work like this (this is the only thing implemented ATM):

`python D3Edit.py -i account.dat -o account_mod.dat -s 0 --gold 999999999`
In development:
----
- Item Edition safe mode (easier to make legal items).

```
usage: D3Edit.py [-h] -i IN_FILE [-o OUT_FILE] [-s SLOT]
[--gold GOLD]
[--blood-shards BLOOD_SHARDS]
[--reusable-parts REUSABLE_PARTS] [--arcane-dust ARCANE_DUST]
[--veiled-crystals VEILED_CRYSTALS]
[--deaths-breath DEATHS_BREATH]
[--forgotten-souls FORGOTTEN_SOULS]
[--khanduran-runes KHANDURAN_RUNES]
[--caldeum-nightshade CALDEUM_NIGHTSHADE]
[--arreat-war-tapestries ARREAT_WAR_TAPESTRIES]
[--corrupted-angel-flesh CORRUPTED_ANGEL_FLESH]
[--westmarch-holy-water WESTMARCH_HOLY_WATER]
[--hearts-of-fright HEARTS_OF_FRIGHT]
[--vials-of-putridness VIALS_OF_PUTRIDNESS]
[--idols-of-terror IDOLS_OF_TERROR]
[--leorics-regrets LEORICS_REGRETS]
[--vengeful-eyes VENGEFUL_EYES]
[--writhing-spines WRITHING_SPINES]
[--devils-fangs DEVILS_FANGS]
[--all-currencies ALL_CURRENCIES]
Help needed:
----
Help needed identifying the missing items and affixes.
If you find a missing item please report back.

A script to encrypt/decrypt and modify Diablo III saves

optional arguments:
-h, --help
show this help message and exit
-i IN_FILE, --in-file IN_FILE
The account file you want to work with
-o OUT_FILE, --out-file OUT_FILE
The account file you want to output to
Credits:
> https://github.com/fry -> Diablo III Protobin Decompiler

selection:
-s SLOT, --slot SLOT
The slot ID you want to work with
> https://github.com/VisualStudio-zz -> Original creator of the python CLI tool.

modifications:
--gold GOLD
Set the amount of gold
--blood-shards BLOOD_SHARDS
Set the amount of blood shards
--reusable-parts REUSABLE_PARTS
Set the amount of reusable parts
--arcane-dust ARCANE_DUST
Set the amount of arcane dust
--veiled-crystals VEILED_CRYSTALS
Set the amount of veiled crystals
--deaths-breath DEATHS_BREATH
Set the amount of death's breath
--forgotten-souls FORGOTTEN_SOULS
Set the amount of forgotten souls
--khanduran-runes KHANDURAN_RUNES
Set the amount of khanduran runes
--caldeum-nightshade CALDEUM_NIGHTSHADE
Set the amount of caldeum nightshade
--arreat-war-tapestries ARREAT_WAR_TAPESTRIES
Set the amount of arreat war tapestries
--corrupted-angel-flesh CORRUPTED_ANGEL_FLESH
Set the amount of corrupted angel flesh
--westmarch-holy-water WESTMARCH_HOLY_WATER
Set the amount of westmarch holy water
--hearts-of-fright HEARTS_OF_FRIGHT
Set the amount of hearts of fright
--vials-of-putridness VIALS_OF_PUTRIDNESS
Set the amount of vials of putridness
--idols-of-terror IDOLS_OF_TERROR
Set the amount of idols of terror
--leorics-regrets LEORICS_REGRETS
Set the amount of leoric's regrets
--vengeful-eyes VENGEFUL_EYES
Set the amount of vengeful eyes
--writhing-spines WRITHING_SPINES
Set the amount of writhing spines
--devils-fangs DEVILS_FANGS
Set the amount of devil's fangs
--all-currencies ALL_CURRENCIES
Set all currencies to the given value
```
> https://github.com/sixwings -> Primal item affix, various database items and gui improvements.

Credits:
> https://github.com/fry -> Diablo III Protobin Decompiler
> GBATemp user - RobertIII -> Identifying the item flag for Primal items.
Loading