File size: 4,497 Bytes
b6a38d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
function NetRecord(label, ...)
	if not config.SwarmConnect then return end
	local _, context = ...
	local rec = Serialize(LuaRevision, os.time(), label, ...)
	CreateRealTimeThread(function(rec, context)
		local err = NetCall("rfnRec", Unserialize(rec))
		--do not try to save the account storage if the error originated from trying to save it in the first place
		if err and rawget(_G, "AccountStorage") and context ~= "account save" then
			AccountStorage.NetRecord = AccountStorage.NetRecord or {}
			AccountStorage.NetRecord[#AccountStorage.NetRecord + 1] = rec
			if #AccountStorage.NetRecord > 100 then
				table.remove(AccountStorage.NetRecord, 1)
			end
			SaveAccountStorage(30000)
		end
	end, rec, context)
end

-- log the most recent crash files to the server
function LogLatestCrash()
	if not (Platform.pc or Platform.osx or Platform.linux) or g_bCrashReported then return end
	-- find the most recent one
	g_bCrashReported = true
	local crash_files, latest_crash_file, latest_crash_date = GetCrashFiles("*.crash")
	if not latest_crash_file then
		return
	end
	local err, crash_log = AsyncFileToString(latest_crash_file)
	if err then
		return
	end
	
	local filename = tostring(latest_crash_date or os.date("!%d %b %Y %H:%M:%S"))
	NetLogFile("crash", filename, "crash", crash_log)
	
	if Platform.osx then
		local reports_dir = "/Users/" .. GetUsername() .. "/Library/Logs/DiagnosticReports"
		local reports_pattern = GetExecName() .. "_*.crash"
		local _, reports = AsyncListFiles(reports_dir, reports_pattern, "recursive,modified")
		reports = reports or {}
		
		for i=1, #(reports.modified or "") do
			reports.modified[i] = reports.modified[i] - latest_crash_date
		end
		
		local _, report_index = table.min(reports.modified or "")
		local report = reports[report_index] or ""
		
		local _, report_dump = AsyncFileToString(report)
		NetLogFile("crash", filename, "xdmp", report_dump)
		AsyncFileDelete(reports)
	else
		local dump_ext = Platform.linux and "ldmp" or "dmp"
		local dump_file = string.gsub(latest_crash_file, "%.crash$", "." .. dump_ext)--gsub returns 2 results, do not pass as function argument!!!
		local _, crash_dump = AsyncFileToString(dump_file)
		NetLogFile("crash", filename, dump_ext, crash_dump)
	end
	
	if #crash_files > 0 then
		NetGossip("Crashes",  #crash_files)	
	end
	EmptyCrashFolder()
end

function OnMsg.NetConnect()
	CreateRealTimeThread(function()
		local display = GetMainWindowDisplayIndex()
		NetGossip("Hardware", GetHardwareInfo(EngineOptions.GraphicsApi, EngineOptions.GraphicsAdapterIndex), GetFullEngineOptions())
		LogLatestCrash()
		if rawget(_G, "AccountStorage") and AccountStorage.NetRecord and AccountStorage.NetRecord[1] then
			while AccountStorage.NetRecord[1] do
				local err = NetCall("rfnRec", Unserialize(AccountStorage.NetRecord[1]))
				if err == "disconnected" then break end
				table.remove(AccountStorage.NetRecord, 1)
			end
			SaveAccountStorage(30000)
		end
	end)
end

if FirstLoad then
	g_TryConnectToServerThread = false
end

-- config.SwarmConnect can be false, "ping" or "reconnect"
function TryConnectToServer()
	if Platform.cmdline then return end
	g_TryConnectToServerThread = g_TryConnectToServerThread or CreateRealTimeThread(function()
		WaitInitialDlcLoad()
		while not AccountStorage do
			WaitMsg("AccountStorageChanged")
		end
		if Platform.xbox then
			WaitMsg("XboxUserSignedIn")
		end
		local wait = 60*1000
		while config.SwarmConnect do
			if not NetIsConnected() then
				local err, auth_provider, auth_provider_data, display_name = NetGetProviderLogin(false)
				if err then
					err, auth_provider, auth_provider_data, display_name = NetGetAutoLogin()
				end
				err = err or NetConnect(config.SwarmHost, config.SwarmPort, 
					auth_provider, auth_provider_data, display_name, config.NetCheckUpdates, "netClient")
				if err == "failed" or err == "version" then -- if we cannot login with these credentials stop trying
					return
				end
				if not err and config.SwarmConnect == "ping" or err == "bye" then
					NetDisconnect("netClient")
					return
				end
				wait = wait * 2 -- double the wait time on fail
				if err == "maintenance" or err == "not ready" then
					wait = 5*60*1000 -- wait exactly 5 mins if servers are not ready
				end
			end
			if NetIsConnected() then
				wait = 60*1000 -- on success reset the wait time
				if config.SwarmConnect == "ping" then
					NetDisconnect("netClient")
					return
				end
				WaitMsg("NetDisconnect")
			end
			Sleep(wait)
		end
	end)
end