<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Thursday, October 11, 2018, 7:12 PM -->
<!-- MuClient version 5.05 -->

<!-- Plugin "CosmicRage" generated by Plugin Wizard -->

<muclient>
<plugin
   name="CosmicRage"
   author="The Cosmic Rage hosting team"
   id="57139deb42b490952946f9e4"
   language="Lua"
   purpose="Main plugin for Cosmic Rage, which holds the main triggers, keystrokes, and functions."
   date_written="2004-08-26 19:06:10"
   requires="4.82"
   version="1.0"
sequence="10000"
   >

</plugin>

<script>
<![CDATA[
for i = 1, 9 do
Accelerator("alt + " .. i, "@buffer " .. i)
end
Accelerator("alt + 0", "@buffer 10")
Accelerator("alt + right", "@buffer forward")
Accelerator("alt + left", "@buffer backward")
Accelerator("alt + down", "@buffer down")
Accelerator("alt + up", "@buffer up")
Accelerator("alt + pagedown", "@buffer scrolldown")
Accelerator("alt + pageup", "@buffer scrollup")
Accelerator("alt + end", "@buffer bottom")
Accelerator("alt + home", "@buffer top")
Accelerator("alt+delete", "@buffer clear")
Accelerator("alt+shift+delete", "@buffer clearall")
Accelerator("alt+shift+right", "@buffer add")
Accelerator("alt+shift+left", "@buffer delete")
Accelerator("f4", "@sp-settings master volume")
Accelerator("f5", "@sp-settings General volume")
Accelerator("f6", "@sp-settings ambiance volume")
Accelerator("f7", "@sp-settings in and out of character communications volume")
Accelerator("f8", "@sp-settings planetary music volume")
Accelerator("ctrl+f5", "@sp-settings clocks volume")
Accelerator("ctrl+f6", "@sp-settings Combat music volume")
Accelerator("ctrl+f7", "@sp-settings IC social volume")
Accelerator("ctrl+f8", "@sp-settings OOC social volume")
Accelerator("alt+f5", "@sp-settings Ground Combat volume")
Accelerator("alt+f6", "@sp-settings harvesting activity volume")
Accelerator("alt+f7", "@sp-settings Salvage activity volume")
Accelerator("alt+f8", "@sp-settings volume for games such as Pilot's Parody")
Accelerator("shift+f5", "@sp-settings starship combat volume")
Accelerator("shift+f6", "@sp-settings ship volume")
Accelerator("shift+f7", "@sp-settings ship movement volume")
Accelerator("shift+f8", "@sp-settings vehicle volume")
Accelerator("f9", "@sp-settings IC social sounds")
Accelerator("f10", "@sp-settings OOC social sounds")
Accelerator("alt+f9", "@sp-settings panning of sounds")
Accelerator("alt+f10", "@sp-settings pitch-shifting sounds")
Accelerator("alt+f11", "@sp-settings ambiance")
Accelerator("ctrl+f9", "@sp-settings planetary music")
Accelerator("ctrl+f10", "@sp-settings space combat music")
Accelerator("ctrl+f11", "@sp-settings weather sounds")
Accelerator("shift+alt+f9", "@sp-settings Interrupt OOC Social sounds when the next one plays")
Accelerator("f2", "@sp-settings")
Accelerator("shift+f1", "@sp-toggle")
Accelerator("Ctrl+shift+enter", "@sp-settings buffer sounds")
Accelerator("ctrl+shift+v", "@sp-version")
Accelerator("ctrl+s", "save_state_func")
Accelerator("alt+shift+h", "localsphelp")
Accelerator("ctrl+f2", "mainvoldown")
Accelerator("ctrl+f3", "mainvolup")
Accelerator("alt+f3", "intromusictoggle")
Accelerator("ctrl+f1", "smute")
Accelerator("f11", "f11_stop")
Accelerator("alt+f12", "alt_f12_stop")

function save_state_func()
  SaveState()
  Execute("tts_interrupt Client-side Soundpack Settings have been saved successfully!")
end

function f11_stop()
  ppi.stop(0)
  Execute("tts_interrupt All currently playing sounds have been stopped.")
  Send("@sp-restart")
end

function alt_f12_stop()
  ppi.stop(0)
  Execute("tts_interrupt All currently playing sounds have been stopped.")
end


function RegisterMushClient(name, line, wildcards)
  DoAfter(1, '@sp-register mush')
end

-- Define the latest soundpack version here
CURRENT_SP_VERSION = 5

function CheckSoundpackVersion(name, line, wildcards, styles)
  local user_version = tonumber(wildcards.user_version)
  if not user_version then
    ColourNote("red", "", "Error: Could not read your soundpack version.")
    return
  end

Note("You are currently running version " .. tostring(CURRENT_SP_VERSION).." of the Cosmic Rage Mush Immersion.")

  local version_diff = user_version - CURRENT_SP_VERSION

  if version_diff > 0 then
    ColourNote("yellow", "", "Warning: Your soundpack is " .. version_diff .. " version(s) out of date. We are now on version " .. user_version .. " of the soundpack.")
    ColourNote("yellow", "", "Launching the updater...")
    ppi.play(dir.."sounds/ogg/general/comms/announcement.ogg", 0, 0, 100)
    -- dir is the world's own folder (cosmic rage\worlds\Cosmic Rage\);
    -- updator.bat lives at the repo root, three levels up from there.
    local bat_path = dir .. "..\\..\\..\\updator.bat"
    -- Signature is (filename, params, defdir, operation, show) - this was
    -- previously passing "open" as the filename, so it never actually
    -- launched cmd.exe/updator.bat at all.
    utils.shellexecute("cmd", '/c "' .. bat_path .. '"', "", "open", 1)
    ColourNote("yellow", "", "The updater has been launched in a separate window. Once the update is complete, please restart MUSHclient to apply the updates!")
    Execute("tts_interrupt Warning: Your soundpack is out of date. The updater has been launched. Once the update is complete, please restart MUSHclient to apply the updates!")
  else
    ColourNote("green", "", "Your soundpack is up to date!")
  end
end

function url_encode(str)
  return (str:gsub("([^%w%-%_%.%~%/])", function(c)
    return string.format("%%%02X", string.byte(c))
  end))
end

pending_downloads = {}
pending_play = {}

function download_sound(path, action, pan, volume, pitch, id)
  if pending_downloads[path] then
    table.insert(pending_play[path], {action=action, pan=pan, volume=volume, pitch=pitch, id=id})
    return
  end

  pending_downloads[path] = os.time()
  pending_play[path] = { {action=action, pan=pan, volume=volume, pitch=pitch, id=id} }

  local sound_path = dir .. "sounds/ogg/" .. path .. ".ogg"
  local safe_path  = sound_path:gsub("/", "\\")
  local parent_dir = safe_path:match("^(.+)\\[^\\]+$")
  local encoded_path = url_encode(path)
  local url = "http://nathantech.net:3000/CosmicRage/CosmicRageSounds/raw/branch/main/ogg/" .. encoded_path .. ".ogg"

  -- Download to a .part file and only rename it to the real filename after
  -- curl succeeds, so check_downloads() can never mistake a half-written or
  -- failed transfer for a completed one. Clears any leftover .err first, and
  -- deletes it again on success, so a stale error/empty file can't linger.
  local cmd_args = string.format(
    '/C mkdir "%s" 2>nul & del /q "%s.err" 2>nul & ' ..
    'curl.exe -s -S -L -f -o "%s.part" "%s" 2>"%s.err" ' ..
    '&& (move /y "%s.part" "%s" >nul & del /q "%s.err" 2>nul) || del /q "%s.part" 2>nul',
    parent_dir, safe_path, safe_path, url, safe_path, safe_path, safe_path, safe_path, safe_path
  )
  -- NOTE: correct shellexecute signature is (filename, params, defdir, operation, show)
  utils.shellexecute("cmd", cmd_args, "", "open", 0)
end

-- If a download hasn't finished or failed within this long, give up on it
-- rather than let a stuck curl process silently block that sound forever.
DOWNLOAD_TIMEOUT_SECONDS = 30

function check_downloads(name)
  for path, started_at in pairs(pending_downloads) do
    local sound_path = dir .. "sounds/ogg/" .. path .. ".ogg"
    local safe_path = sound_path:gsub("/", "\\")
    local f = io.open(sound_path, "r")
    if f then
      f:close()
      local queue = pending_play[path]
      pending_downloads[path] = nil
      pending_play[path] = nil
      if queue then
        for _, p in ipairs(queue) do
          play_sound_now(path, p.action, p.pan, p.volume, p.pitch, p.id)
        end
      end
    else
      local ef = io.open(safe_path .. ".err", "r")
      if ef then
        local msg = ef:read("*all")
        ef:close()
        if msg and msg ~= "" then
          os.remove(safe_path .. ".err")
          pending_downloads[path] = nil
          pending_play[path] = nil
          Note("Soundpack: download failed for " .. path .. ": " .. msg:gsub("[\r\n]", ""))
        end
      elseif os.time() - started_at > DOWNLOAD_TIMEOUT_SECONDS then
        pending_downloads[path] = nil
        pending_play[path] = nil
        Note("Soundpack: download timed out for " .. path)
      end
    end
  end
end

function play_sound_now(path, action, pan, volume, pitch, id)
  local sound_file = dir.."sounds/ogg/"..path..".ogg"
  local temp
  if (action == "play") then
    temp = ppi.play(sound_file, 0, pan, volume)
    if (pitch > -10000) then
      ppi.setPitch(pitch, temp)
    end
    if (pan > -10000) then
      ppi.setPan(pan, temp)
    end
  elseif (action == "playrec") then
    temp = ppi.play(sound_file, 0, pan, volume)
    SetVariable(id, temp)
    if (pitch > -10000) then
      ppi.setPitch(pitch, temp)
    end
    if (pan > -10000) then
      ppi.setPan(pan, temp)
    end
  elseif (action == "loop") then
    temp = ppi.play(sound_file, 1, pan, volume)
    SetVariable(id, temp)
    if (pitch > -10000) then
      ppi.setPitch(pitch, temp)
    end
    if (pan > -10000) then
      ppi.setPan(pan, temp)
    end
  end
end
]]>


dir=world.GetInfo(67)
require "socket.http"
require "ltn12"
PPI = require("ppi")
ppi = PPI.Load("aedf0cb0be5bf045860d54b7")
if not ppi then
  error("Dependency plugin not installed!")
end
</script>

<!--  Get our standard constants -->

<include name="constants.lua"/>

<!--  Triggers  -->
<triggers>
  <trigger
   enabled="y"
   group="hook"
   keep_evaluating="y"
   match = "Welcome to: Cosmic Rage!"
   send_to="12"
   sequence="100"
  >
  <send>
ReloadPlugin("LuaAudio")
local intro = tonumber(GetVariable("intro") or "")
if not intro or ppi.isPlaying(intro) == 0 then
  temp = ppi.play(dir.."sounds/ogg/music/IntroMusic/DefaultIntro.ogg", 1, 0, 40)
  SetVariable("intro", temp)
end
</send>
</trigger>
  <trigger
   enabled="y"
   group="hook"
   keep_evaluating="y"
   match = "synaptic signal verified. Sleep mode disengaged. Welcome back to Cosmic Rage!"
   send_to="12"
   sequence="100"
script="RegisterMushClient"
  >
  <send>
  temp=GetVariable("intro")
  ppi.stop(temp)
</send>
</trigger>

  <trigger
   enabled="y"
   group="hook"
   keep_evaluating="y"
   match = "Your synaptic signal wavers for a moment, then returns with a snap!"
   send_to="12"
   sequence="100"
script="RegisterMushClient"
  >
  <send>
  temp=GetVariable("intro")
  ppi.stop(temp)
</send>
</trigger>

<trigger
   enabled="y"
   group="hook"
   omit_from_output="y"
   match="^\$soundpack mush last version: (?P<user_version>\d+)"
   regexp="y"
   script="CheckSoundpackVersion"
   sequence="100"
/>


  <trigger
   enabled="y"
   group="hook"
   omit_from_output="y"
   keep_evaluating="n"
match="^\$sphook\s+(?P<action>[\w]+):(?P<path>[-\w./\\\s]+):(?P<volume>[\w]+):(?P<pitch>[\w-]+):(?P<pan>[\w-]+):(?P<id>[\w]+)$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
  action="%1"
  path="%2"
  volume="%3"
  pitch="%4"
  pan="%5"
  id="%6"
  volume=tonumber(volume)
  
  if (pitch == "na") then
    pitch = -10000
  else
    pitch = tonumber(pitch)
    pitch = (pitch - 44100) / 98
  end

  if (pan == "na") then
    pan = -10000
  else
    pan = tonumber(pan)
  end

  if (path == "na") then
    if (action == "adjustsound") then
      temp = GetVariable(id)
      if volume and volume > -1 then
        ppi.setVol(volume, temp)
      end
      if (pitch > -10000) then
        ppi.setPitch(pitch, temp)
      end
      if (pan > -10000) then
        ppi.setPan(pan, temp)
      end
    elseif (action == "stop") then
      temp = GetVariable(id)
      if temp then
        ppi.stop(temp)
      end
    end
  else
    local sound_path = dir .. "sounds/ogg/" .. path .. ".ogg"
    local file = io.open(sound_path, "r")
    if file then
      file:close()
      play_sound_now(path, action, pan, volume, pitch, id)
    else
      download_sound(path, action, pan, volume, pitch, id)
    end
  end
  </send>
  </trigger>
    </triggers>

<!--  Timers  -->
<timers>
  <timer
   enabled="y"
   second="0.5"
   script="check_downloads"
  >
  </timer>
</timers>



<aliases>
  <alias
   match="f11_stop"
   enabled="y"
   script="f11_stop"
   omit_from_output="y"
   omit_from_log="y"
   omit_from_command_history="y"
   send_to="12"
   sequence="100"
  >
  </alias>
  <alias
   match="alt_f12_stop"
   enabled="y"
   script="alt_f12_stop"
   omit_from_output="y"
   omit_from_log="y"
   omit_from_command_history="y"
   send_to="12"
   sequence="100"
  >
  </alias>
  </aliases>

</muclient>