Advertisement
MrFinn

ComputerCraft - Glados server

Dec 1st, 2024 (edited)
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.80 KB | None | 0 0
  1. -- Configuration
  2. local TEXT_SCALE = 2 -- Text size (0.5, 1, 2, ...)
  3. local TEXT_COLOR = colors.orange -- Text color (use colors.<color>)
  4.  
  5. -- HTTP API setup
  6. assert(http, "HTTP API is not enabled. Check your ComputerCraft config.")
  7. local API_URL = "https://lordfinn.fr/api/ask-glados"
  8.  
  9. -- Wireless modem setup
  10. local modem = peripheral.wrap("left")
  11. assert(modem, "Wireless modem not connected.")
  12. modem.open(1)
  13.  
  14. local cable_modem = peripheral.wrap("bottom")
  15.  
  16. local link = peripheral.wrap("top")
  17.  
  18. -- Function to get all connected speakers
  19. local function getSpeakers()
  20. local speakers = {}
  21. for _, name in ipairs(peripheral.getNames()) do
  22. if peripheral.getType(name) == "speaker" then
  23. table.insert(speakers, peripheral.wrap(name))
  24. end
  25. end
  26. return speakers
  27. end
  28.  
  29. -- Function to play text-to-speech on all speakers
  30. local function playTextToSpeech()
  31. local url = API_URL .. "/last-audio"
  32. local response, err = http.get({ url = url, binary = true })
  33. if not response then
  34. print("Error fetching TTS audio: " .. err)
  35. return
  36. end
  37.  
  38. local decoder = require("cc.audio.dfpwm").make_decoder()
  39. local speakers = getSpeakers()
  40.  
  41. if #speakers == 0 then
  42. print("No speakers found!")
  43. return
  44. end
  45.  
  46. while true do
  47. local chunk = response.read(16 * 1024)
  48. if not chunk then break end
  49.  
  50. local buffer = decoder(chunk)
  51. for _, speaker in ipairs(speakers) do
  52. while not speaker.playAudio(buffer) do
  53. os.pullEvent("speaker_audio_empty")
  54. end
  55. end
  56. end
  57. response.close()
  58. end
  59.  
  60. local function sanitizeText(text)
  61. -- Replace UTF-8 artifacts with proper characters
  62. text = text:gsub("é", "é"):gsub("è", "è"):gsub("ê", "ê"):gsub("ë", "ë")
  63. text = text:gsub("Ã ", "à"):gsub("Ã ", "â"):gsub("Ã ", "ä")
  64. local replacements = {
  65. ["é"] = "&", ["è"] = "e", ["ê"] = "ai", ["ë"] = "ai",
  66. ["à"] = "a", ["â"] = "a", ["ä"] = "a",
  67. ["ç"] = "c",
  68. ["ù"] = "u", ["û"] = "u", ["ü"] = "u",
  69. ["î"] = "i", ["ï"] = "i",
  70. ["ô"] = "o", ["ö"] = "o",
  71. ["â"] = "a", ["ã"] = "a",
  72. ["œ"] = "e", ["æ"] = "a",
  73. ["ÿ"] = "y",
  74. ["É"] = "er", ["È"] = "ai", ["Ê"] = "ai", ["Ë"] = "ai",
  75. ["À"] = "A", ["Â"] = "A", ["Ä"] = "A",
  76. ["Ç"] = "C",
  77. ["Ù"] = "U", ["Û"] = "U", ["Ü"] = "U",
  78. ["Î"] = "I", ["Ï"] = "I",
  79. ["Ô"] = "O", ["Ö"] = "O",
  80. ["Â"] = "A", ["Ã"] = "A",
  81. ["Œ"] = "e", ["Æ"] = "a",
  82. ["Ÿ"] = "Y"
  83. }
  84. -- Replace each character in the text based on the replacements table
  85. for original, replacement in pairs(replacements) do
  86. text = text:gsub(original, replacement)
  87. end
  88. return text
  89. end
  90.  
  91. local function playSpeakerBlocks(response)
  92. link.clear()
  93. link.write(sanitizeText(response))
  94. link.update()
  95. rs.setOutput("right", true)
  96. os.sleep(1)
  97. rs.setOutput("right", false)
  98. end
  99.  
  100. -- Function to display the last response
  101. local function displayLastResponse()
  102. local url = API_URL .. "/last"
  103. local response, err = http.get(url)
  104. if not response then
  105. print("Error fetching last response: " .. err)
  106. return
  107. end
  108.  
  109. local responseBody = textutils.unserializeJSON(response.readAll())
  110. response.close()
  111.  
  112. if responseBody and responseBody.response then
  113. -- Send message to clients
  114. modem.transmit(1, 1, responseBody.response)
  115. else
  116. modem.transmit(1, 1, "No last response available.")
  117. end
  118. end
  119.  
  120. -- Main function
  121. local function main()
  122. -- Display and send the last response on startup
  123. displayLastResponse()
  124.  
  125. print("Type a message to ask GLaDOS:")
  126. while true do
  127. write("> ")
  128. local userInput = read()
  129. if userInput and userInput ~= "" then
  130. print("Asking GLaDOS...")
  131. modem.transmit(1, 1, "Thinking...")
  132.  
  133. local response, err = http.post(API_URL, textutils.serializeJSON({ question = userInput }), { ["Content-Type"] = "application/json" })
  134. if not response then
  135. print("Error: " .. (err or "Unknown error"))
  136. modem.transmit(1, 1, "Error contacting GLaDOS.")
  137. else
  138. local responseBody = textutils.unserializeJSON(response.readAll())
  139. response.close()
  140.  
  141. if responseBody and responseBody.response then
  142. modem.transmit(1, 1, responseBody.response)
  143. playSpeakerBlocks(responseBody.response)
  144. playTextToSpeech()
  145. end
  146. end
  147. else
  148. print("Please enter a valid question.")
  149. end
  150. end
  151. end
  152.  
  153. main()
  154.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement