forked from githtz/mpd
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.lua
More file actions
214 lines (199 loc) · 6.05 KB
/
init.lua
File metadata and controls
214 lines (199 loc) · 6.05 KB
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
mpd={}
mpd.pause_between_songs=minetest.settings:get("mpd.pause_between_songs") or 30
--end config
mpd.modpath=minetest.get_modpath("mpd")
if not mpd.modpath then
error("mpd mod folder has to be named 'mpd'!")
end
--{name, length, gain~1}
mpd.songs = {}
local sfile, sfileerr=io.open(mpd.modpath..DIR_DELIM.."songs.txt")
if not sfile then error("Error opening songs.txt: "..sfileerr) end
for linent in sfile:lines() do
-- trim leading and trailing spaces away
local line = string.match(linent, "^%s*(.-)%s*$")
if line~="" and string.sub(line,1,1)~="#" then
local name, timeMinsStr, timeSecsStr, gainStr, title = string.match(line, "^(%S+)%s+(%d+):([%d%.]+)%s+([%d%.]+)%s*(.*)$")
local timeMins, timeSecs, gain = tonumber(timeMinsStr), tonumber(timeSecsStr), tonumber(gainStr)
if title=="" then title = name end
if name and timeMins and timeSecs and gain then
mpd.songs[#mpd.songs+1]={name=name, length=timeMins*60+timeSecs, lengthhr=timeMinsStr..":"..timeSecsStr, gain=gain, title=title}
else
minetest.log("warning", "[mpd] Misformatted song entry in songs.txt: "..line)
end
end
end
sfile:close()
if #mpd.songs==0 then
print("[mpd]no songs registered, not doing anything")
return
end
mpd.storage = minetest.get_mod_storage()
mpd.handles={}
mpd.playing=false
mpd.id_playing=nil
mpd.song_time_left=nil
mpd.time_next=10 --sekunden
mpd.id_last_played=nil
minetest.register_globalstep(function(dtime)
if mpd.playing then
if mpd.song_time_left<=0 then
mpd.stop_song()
mpd.time_next=mpd.pause_between_songs
else
mpd.song_time_left=mpd.song_time_left-dtime
end
elseif mpd.time_next then
if mpd.time_next<=0 then
mpd.next_song()
else
mpd.time_next=mpd.time_next-dtime
end
end
end)
mpd.play_song=function(id)
if mpd.playing then
mpd.stop_song()
end
local song=mpd.songs[id]
if not song then return end
for _,player in ipairs(minetest.get_connected_players()) do
local pname=player:get_player_name()
local pvolume=tonumber(mpd.storage:get_string("vol_"..pname))
if not pvolume then pvolume=1 end
if pvolume>0 then
local handle = minetest.sound_play(song.name, {to_player=pname, gain=song.gain*pvolume})
if handle then
mpd.handles[pname]=handle
end
end
end
mpd.playing=id
--adding 2 seconds as security
mpd.song_time_left = song.length + 2
end
mpd.stop_song=function()
for pname, handle in pairs(mpd.handles) do
minetest.sound_stop(handle)
end
mpd.id_last_played=mpd.playing
mpd.playing=nil
mpd.handles={}
mpd.time_next=nil
end
mpd.next_song=function()
local next
repeat
next=math.random(1,#mpd.songs)
until #mpd.songs==1 or next~=mpd.id_last_played
mpd.play_song(next)
end
mpd.song_human_readable=function(id)
if not tonumber(id) then return "<error>" end
local song=mpd.songs[id]
if not song then return "<error>" end
return id..": "..song.title.." ["..song.lengthhr.."]"
end
minetest.register_privilege("mpd", "may control the music player daemon (mpd) mod")
minetest.register_chatcommand("mpd_stop", {
params = "",
description = "Stop the song currently playing",
privs = {mpd=true},
func = function(name, param)
mpd.stop_song()
end,
})
minetest.register_chatcommand("mpd_list", {
params = "",
description = "List all available songs and their IDs",
privs = {mpd=true},
func = function(name, param)
for k,v in ipairs(mpd.songs) do
minetest.chat_send_player(name, mpd.song_human_readable(k))
end
end,
})
minetest.register_chatcommand("mpd_play", {
params = "<id>",
description = "Play the songs with the given ID (see ids with /mpd_list)",
privs = {mpd=true},
func = function(name, param)
if param=="" then
mpd.next_song()
return true,"Playing: "..mpd.song_human_readable(mpd.playing)
end
id=tonumber(param)
if id and id>0 and id<=#mpd.songs then
mpd.play_song(id)
return true,"Playing: "..mpd.song_human_readable(id)
end
return false, "Invalid song ID!"
end,
})
minetest.register_chatcommand("mpd_what", {
params = "",
description = "Display the currently played song.",
privs = {mpd=true},
func = function(name, param)
if not mpd.playing then
if mpd.time_next and mpd.time_next~=0 then
return true,"Nothing playing, "..math.floor(mpd.time_next or 0).." sec. left until next song."
else
return true,"Nothing playing."
end
end
return true,"Playing: "..mpd.song_human_readable(mpd.playing).."\nTime Left: "..math.floor(mpd.song_time_left or 0).." sec."
end,
})
minetest.register_chatcommand("mpd_next", {
params = "[seconds]",
description = "Start the next song, either immediately (no parameters) or after n seconds.",
privs = {mpd=true},
func = function(name, param)
mpd.stop_song()
if param and tonumber(param) then
mpd.time_next=tonumber(param)
return true,"Next song in "..param.." seconds!"
else
mpd.next_song()
return true,"Next song started!"
end
end,
})
minetest.register_chatcommand("mvolume", {
params = "[volume level (0-1)]",
description = "Set your background music volume. Use /mvolume 0 to turn off background music for you. Without parameters, show your current setting.",
privs = {},
func = function(pname, param)
if not param or param=="" then
local pvolume=tonumber(mpd.storage:get_string("vol_"..pname))
if not pvolume then pvolume=1 end
if pvolume>0 then
return true, "Your music volume is set to "..pvolume.."."
else
if mpd.handles[pname] then
minetest.sound_stop(mpd.handles[pname])
end
return true, "Background music is disabled for you. Use '/mvolume 1' to enable it again."
end
end
local pvolume=tonumber(param)
if not pvolume then
return false, "Invalid usage: /mvolume [volume level (0-1)]"
end
pvolume = math.min(pvolume, 1)
pvolume = math.max(pvolume, 0)
mpd.storage:set_string("vol_"..pname, pvolume)
if pvolume>0 then
return true, "Music volume set to "..pvolume..". Change will take effect when the next song starts."
else
if mpd.handles[pname] then
minetest.sound_stop(mpd.handles[pname])
end
return true, "Disabled background music for you. Use /mvolume to enable it again."
end
end,
})
if vote then
dofile(mpd.modpath..DIR_DELIM.."vote.lua")
end