summaryrefslogtreecommitdiffstatshomepage
path: root/plugins/data/data_marp.lua
blob: 09fddf11ef9ccfec776893ea00f116433896331e (plain) (blame)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
-- get marp high score file from http://replay.marpirc.net/txt/scores3.htm
local dat = {}

local db = require("data/database")
local ver, info

local function init()
	local file = 'scores3.htm'

	local fh, filepath, tablename, dbver = db.open_data_file(file)
	if not fh then
		if dbver then
			-- data in database but missing file, just use what we have
			ver = dbver
		end
		return
	end

	-- scan file for version
	for line in fh:lines() do
		local match = line:match('Top Scores from the MAME Action Replay Page %(([%w :]+)%)')
		if match then
			ver = match
			break
		end
	end
	if (not ver) or (ver == dbver) then
		fh:close()
		ver = dbver
		return
	end

	if not dbver then
		db.exec(
			string.format(
				[[CREATE TABLE "%s" (
					romset VARCHAR NOT NULL,
					data CLOB NOT NULL,
					PRIMARY KEY(romset));]],
				tablename))
		db.check('creating MARP table')
	end

	db.exec([[BEGIN TRANSACTION;]])
	if not db.check('starting MARP transaction') then
		fh:close()
		ver = dbver
		return
	end

	-- clean out previous data and update the version
	if dbver then
		db.exec(string.format([[DELETE FROM "%s";]], tablename))
		if not db.check('deleting previous MARP data') then
			db.exec([[ROLLBACK TRANSACTION;]])
			fh:close()
			ver = dbver
			return
		end
	end
	if not db.set_version(file, ver) then
		db.check('updating MARP version')
		db.exec([[ROLLBACK TRANSACTION;]])
		fh:close()
		ver = dbver
		return
	end

	fh:seek('set')
	local buffer = fh:read('a')

	local function gmatchpos()
		local pos = 1
		local set = ''
		local data = ''
		local function iter()
			local lastset = set
			while true do
				local spos, scr, plyr, stype, ltype
				spos, pos, set, stype, scr, plyr, ltype = buffer:find('\n%s*([%w_]*)%-?(%w-) :%s*(%d+) [;:] ([^:]+): [^%[\n]*%[?([%w ]*)[^\n]*', pos)
				if not spos then
					return nil
				end

				local url = ''
				if set ~= '' then
					if ltype ~= '' then
						url = ltype .. '\t\n'
					end
					url = url .. 'http://replay.marpirc.net/r/' .. set
					if stype ~= '' then
						url = url .. '-' .. stype
					end
					url = url .. '\t\n'
				end

				if (set ~= '') and (lastset ~= set) then
					local lastdata = data
					data = url .. plyr .. '\t' .. scr .. '\n'
					return lastset, lastdata
				end

				if url ~= '' then
					data = data .. '\n' .. url
				end
				data = data .. plyr .. '\t' .. scr .. '\n'
			end
		end
		return iter
	end

	local query = db.prepare(
		string.format([[INSERT INTO "%s" (romset, data) VALUES (?, ?)]], tablename))
	for set, data in gmatchpos() do
		query:bind_values(set, data)
		while true do
			local status = query:step()
			if status == db.DONE then
				break
			elseif status == db.BUSY then
				emu.print_error('Database busy: inserting MARP data')
				query:finalize()
				db.exec([[ROLLBACK TRANSACTION;]])
				fh:close()
				ver = dbver
				return
			elseif result ~= db.ROW then
				db.check('inserting MARP data')
				break
			end
		end
		query:reset()
	end
	query:finalize()

	fh:close()
	db.exec([[COMMIT TRANSACTION;]])
	if not db.check('committing MARP transaction') then
		db.exec([[ROLLBACK TRANSACTION;]])
		ver = dbver
	end
end

if db then
	init()
end

function dat.check(set, softlist)
	if softlist or (not ver) then
		return nil
	end

	info = nil
	local query = db.prepare([[SELECT data FROM "scores3.htm" WHERE romset = ?;]])
	query:bind_values(set)
	while not info do
		local status = query:step()
		if status == db.ROW then
			info = '#j2\n' .. query:get_value(0)
		elseif status == db.DONE then
			break
		elseif status ~= db.BUSY then
			db.check('reading MARP data')
			break
		end
	end
	query:finalize()
	return info and _p('plugin-data', 'MARPScore') or nil
end

function dat.get()
	return info
end

function dat.ver()
	return ver
end

return dat