It's been a while since I uploaded my latest screenshot to Steam, because mere 4 gigabytes of cloud space granted by Valve got exhausted really fast. In the meantime I still continued to take screenshots, with Steam and with other tools, saving them locally and patiently waiting when upload limits are increased, so I can upload all this stuff again.
And the screenshot space finally got increased to whopping 20 GB! This means we can now upload tons of screenshots we made since the last cloud space bump.
But unfortunately something has changed and now I can't upload any old screenshots. I wrote "custom" in the question's title, but in my case screenshots are custom basically because they were taken with some third party utility or even with PrtScr and Ctrl + V.
The new naming scheme is YYYMMDDHHMMSS_1.jpg, files are still saved to C:\Program Files (x86)\Steam\userdata\<user id>\<some number>\remote\<game id>\screenshots, and when you place your custom screenshots to this folder, Steam screenshot uploader sees them, creates thumbnails, but refuses to upload. Now it only uploads screenshots actually taken with Steam.
So guides like this one became obsolete. The notorious "Steam Cloud may be temporarily unavailable" error appears. I'm sure custom screenshots still can be uploaded, but the whole process apparently now is more tricky.
Anyone able to crack this for us screenshotheads?
163 Answers
The process of uploading a (custom) screenshot is similar to what it used to be.
First find the relevant folder for the game you want to upload screenshots for. This is usually something like C:\Program Files (x86)\Steam\userdata\<user id>\<some number>\remote\<game id>\screenshots\. Refer to this guide (also linked in the question) if you still need help finding the game id. Put your screenshots in that folder. Open steam, right-click the game and click "Show screenshots". Let it load all the thumbnails. Exit the dialog, then exit steam completely (by right-clicking the notification icon and clicking "Exit").
Go to C:\Program Files (x86)\Steam\userdata\<user id>\<some number>\ (that is a few folders above the folder you put your screenshots in, and open screenshots.vdf in an editor that respects both windows and unix line endings, such as VIM or Notepad++. Now find the entry for each of your screenshots. In my case I was searching for the screenshot 20160809224314_2.jpg.
The problem you encountered is because Steam now fills in the vrfilename entry with a non-existing file. Remove that filename so that it says "vrfilename" "". You might need to set imported to "0" depending on if you tried to upload it before.
Save the file, then start steam again. Right-click the game again, then click "show screenshots". It now should allow you to upload your image.
3Well, I promised to come back here with my own solution to this problem, and here I am with a cross-platform open-source utility to simplify the whole process.
At first I thought I'd do it as a Windows batch file, but doesn't provide a good way to work with regular expressions. Then I thought maybe Python script will do it, but hey, nobody wants to install an interpreter and mess with command-line tools. At last I thought I should give Qt a try, and I didn't regret that choice!
Meet SteaScree, Steam Cloud screenshot uploader:
It works in Windows, Linux and macOS.
It's a bit ugly, but Qt has messy UI builder, and this is my first software project in recent times, so please don't judge by the looks.
The sources are shared via GitHub, so if you'd like to report a bug or improve this tool, welcome. This is my first project with Qt, so there may be some issues. Please report them on the GitHub as well.
2Steam doesn't care about filename nor creation date. After you upload screenshot there is only "upload date" displayed. Real date is only used in Screenshots window so you see them ordered properly before upload.
While Sumurai8's answer is complete, some people may have problem with locating proper directory. That's why I wrote script to automate it a bit. It requires Python (you need to install it if you have Windows, other systems should already have it) and VDF Python module.
#!/usr/bin/env python
from __future__ import print_function
from time import sleep
import vdf, platform, os, glob, codecs, subprocess, shutil, time, sys
try: import winreg
except ImportError: import _winreg as winreg
try: input = raw_input
except NameError: pass
def find_default_steam_path(): return { "Windows": lambda: winreg.QueryValueEx( winreg.CreateKey(winreg.HKEY_CURRENT_USER,r"Software\Valve\Steam"), "SteamPath" )[0], "Linux": lambda: os.path.expanduser("~/.local/share/Steam"), "Darwin": lambda: os.path.expanduser("~/Library/Application Support/Steam") }[platform.system()]()
def get_libraries(path): libraries = [path] ignored = ["TimeNextStatsReport", "ContentStatsID"] for k, v in vdf.parse(open(os.path.join(path, "steamapps", "libraryfolders.vdf")))["LibraryFolders"].items(): if k not in ignored: libraries.append(os.path.normpath(v)) return libraries
def get_games_vdfs(libs): vdfs = [] for lib in libs: vdfs += glob.glob(os.path.join(lib, "steamapps", "*.acf")) return vdfs
def get_users(path): users = [] for k, v in vdf.parse(open(os.path.join(path, "config", "loginusers.vdf")))["users"].items(): users.append([v["PersonaName"], str(int(k)-0x110000100000000)]) return sorted(users, key=lambda x: x[0].lower())
def get_user_data(path, user_id): return vdf.parse(codecs.open(os.path.join(path, "userdata", user_id, "config", "localconfig.vdf"), 'r', 'utf8'))["UserLocalConfigStore"]
def get_games(vdfs): games = [] for v in vdfs: game = vdf.parse(open(v))["AppState"] if all(g[1] != game["appid"] for g in games): games.append([game["name"], game["appid"]]) return sorted(games, key=lambda x: x[0].lower())
def filter_user_games(games, user_data): user_games = list(user_data["Licenses"].keys()) + list(user_data["apptickets"].keys()) for game in games: if game[1] not in user_games: games.remove(game)
def get_last_game_index(games, user_data): last_played = ["", 0] for game, v in user_data["Software"]["Valve"]["Steam"]["Apps"].items(): lp = int(v["LastPlayed"]) if lp > last_played[1]: last_played = [game, lp] for i, game in enumerate(games): if game[1] == last_played[0]: return i
steam_path = os.path.normpath(find_default_steam_path())
steam_binary = os.path.join(steam_path, "steam" + (".exe" if platform.system() == "Windows" else ""))
if not os.path.exists(steam_path): steam_path = input("Enter main Steam directory location: ")
users = get_users(steam_path)
libraries = get_libraries(steam_path)
if len(users) == 1: user = users[0]
else: for i, u in enumerate(users): print(i, u[0], sep = ". ") user = users[int(input("Choose user: "))]
user_data = get_user_data(steam_path, user[1])
games_vdfs = get_games_vdfs(libraries)
games = get_games(games_vdfs)
filter_user_games(games, user_data)
last_played_index = get_last_game_index(games, user_data)
print()
for i, g in enumerate(games): print(i, g[0], sep = ". ")
game_choice = input("Choose game or leave empty for last played game (" + games[last_played_index][0] + "): ")
if game_choice == "": game_choice = last_played_index
game = games[int(game_choice)]
print()
screenshot_info_path = os.path.join(steam_path, "userdata", user[1], "760")
dst_path = os.path.join(screenshot_info_path, "remote", game[1], "screenshots")
screenshot_info_path = os.path.join(screenshot_info_path, "screenshots.vdf")
try: os.makedirs(dst_path)
except OSError: pass
src_path = input("Enter source directory: ")
if len(src_path) > 1 and src_path[0] in ('"\'') and src_path[-1] == src_path[0]: src_path = src_path[1:-1]
files_to_move = glob.glob(os.path.join(src_path, "*.[jJ][pP][gG]"))
if len(files_to_move) == 0: input("No files to move. Press Enter to exit.") sys.exit(1)
for file in files_to_move: shutil.move(file, dst_path)
if os.path.exists(screenshot_info_path): size_old = os.stat(screenshot_info_path)[-4]
else: size_old = 0
mod_old = -1
subprocess.Popen([steam_binary, "steam://open/screenshots"])
while True: size_new, _, mod_new = os.stat(screenshot_info_path)[-4:-1] if size_old != size_new: size_old = size_new mod_old = mod_new elif mod_old > -1 and time.time() - mod_old > 3: break sleep(1)
subprocess.call([steam_binary, "-shutdown"])
screenshot_info = vdf.parse(codecs.open(screenshot_info_path, 'r', 'utf8'))
for k, v in screenshot_info["Screenshots"].items(): for k2, v2 in v.items(): screenshot_info["Screenshots"][k][k2]["vrfilename"] = ""
vdf.dump(screenshot_info, codecs.open(screenshot_info_path, 'w', 'utf8'))
input("All done! Wait until Steam client closes and press Enter to start it again.")
subprocess.Popen([steam_binary, "steam://open/screenshots"])How to use?
- Save it for example as
steam_custom_screenshots.py - On Linux and Mac make it executable
- Close Steam
Run script
- If script can't find Steam installation dir, it will ask you for one
- If more than one user logged in to Steam on this computer, script will ask you to choose your account
- You will be asked to choose a game
- You will be asked to choose a path to your screenshots
- Script will now move all
*.jpgfiles from path you entered in previous step to correct directory, start Steam so it imports screenshots, close Steam, editscreenshots.vdffile and wait for you to pressEnterto run Steam again.
If you still have any problem uploading screenshots, delete Steam/userdata/<your ID>/760/screenshots.vdf file and try again. I just uploaded 283 files this way.
Sidenote: There are several default locations of Steam on Linux machines depending on how you install it. I don't know them, so if you want to share one or you know how to find it with Python, let me know in comment.
0