This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
zeronoashaen's profile picture

shell :32: vm error: java.lang.ArrayIndexOutOfBoundsException

Started by zeronoashaen, 18 January 2014 - 01:31 PM
zeronoashaen #1
Posted 18 January 2014 - 02:31 PM
The error in the title comes up when I try to run this program. It uses a lot of custom api's that work perfectly fine in other programs. Any help would be appreciated, and if need be I will post the code from the API's being called.


--**********Load API's**********
os.loadAPI("ocs/apis/sensor")
os.loadAPI("ocLogin")
os.loadAPI("ocgui")
os.loadAPI("ocSQL")
os.loadAPI("ocFunc")

--**********Debug**********
monitorSide = ocFunc.monitorSide()
if monitorSide ~= false then
   debug = true
end

if debug then
   monitor = peripheral.wrap(monitorSide)
end

function newLine()
   if debug then
      local _,cY = monitor.getCursorPos()
      local x, y = monitor.getSize()
      if (cY == y) then
         monitor.setCursorPos(1, 1)
         monitor.clear()
      else
         monitor.setCursorPos(1,cY+1)
      end
   end
end
-
-*********Global Variables**********
sensorSide = ocFunc.sensorSide()
cBlockSide = ocFunc.cBlockSide()
radius = 3
xOffset = 1
yOffset = -1
zOffset = 0

curPlayer = ""
curAcct = ""
flag = ""
acctType = ""

--**********Peripheral Wrapping**********
sensor = sensor.wrap(sensorSide)
--cmdBlock = peripheral.wrap(cBlockSide)



--**********Helper Functions**********
function getItemTableFromToT(tableOfTable, itemRawName, itemDmg)
   for i=1,#tableOfTable do
      textutils.tabulate(tableOfTable[i])
      --if(tableOfTable[i].rawName == itemRawName) then
      if(string.find(tableOfTable[i].rawName, itemRawName, 0, true) ~= nil and string.find(tableOfTable[i].dmg, itemDmg, 0, true) ~= nil) then

         return tableOfTable[i] 
      end
   end
   return nil
end

--**********Screen Creation**********
screenX, screenY = term.getSize()

mainMenu = ocgui.newMenu(screenX - 10, 9, 11, screenY - 8, true, false, false, true, "left")
mainMenu:setBorderTextColour(colors.yellow)
mainMenu:setTextColour(colors.yellow)
mainMenu:setBackgroundColour(colors.blue)

--Just a dummy window to act as a placeholder for the menu until the player is logged in.
mainMenuWindow = ocgui.newWindow(screenX - 10, 9, 11, screenY - 8, true, false, false, true, "left", false)
mainMenuWindow:setBorderTextColour(colors.yellow)
mainMenuWindow:setTextColour(colors.yellow)
mainMenuWindow:setBackgroundColour(colors.blue)

pMenu = ocgui.newMenu(screenX - 10, 9, 11, screenY - 8, true, false, false, true, "left")
pMenu:setBorderTextColour(colors.yellow)
pMenu:setTextColour(colors.yellow)
pMenu:setBackgroundColour(colors.blue)

sMenu = ocgui.newMenu(screenX - 10, 9, 11, screenY - 8, true, false, false, true, "left")
sMenu:setBorderTextColour(colors.yellow)
sMenu:setTextColour(colors.yellow)
sMenu:setBackgroundColour(colors.blue)

ocOverlay = ocgui.newOverlay(1,1,screenX,3,true,false,true,true)
ocOverlay:setHeaderTitle("Outlandcraft", "Exchange System")
ocOverlay:setBorderTextColour(colors.yellow)
ocOverlay:setTextColour(colors.yellow)
ocOverlay:setBackgroundColour(colors.blue)

pOverlay = ocgui.newOverlay(1,1,screenX,3,true,false,true,true)
pOverlay:setHeaderTitle("Outlandcraft", "Exchange System")
pOverlay:setBorderTextColour(colors.yellow)
pOverlay:setTextColour(colors.yellow)
pOverlay:setBackgroundColour(colors.blue)

sOverlay = ocgui.newOverlay(1,1,screenX,3,true,false,true,true)
sOverlay:setHeaderTitle("Outlandcraft", "Exchange System")
sOverlay:setBorderTextColour(colors.yellow)
sOverlay:setTextColour(colors.yellow)
sOverlay:setBackgroundColour(colors.blue)

rightSidebarStatic = ocgui.newWindow(screenX - 10, 4, 11, 5, true, false, false, true, "left", false)
rightSidebarStatic:setBorderTextColour(colors.yellow)
rightSidebarStatic:setTextColour(colors.yellow)
rightSidebarStatic:setBackgroundColour(colors.blue)
rightSidebarStatic:addData("Use mouse,", "or arrows/", "enter to", "navigate.")

rightSidebarBalance = ocgui.newWindow(screenX - 10, (screenY - (screenY * .2)), 11, (screenY * .2), true, true, true, true, "center", false)
rightSidebarBalance:setBorderTextColour(colors.yellow)
rightSidebarBalance:setTextColour(colors.yellow)
rightSidebarBalance:setBackgroundColour(colors.blue)

pMenu = ocgui.newMenu(screenX - 10, 9, 11, screenY - 8, true, false, false, true, "left")
pMenu:setBorderTextColour(colors.yellow)
pMenu:setTextColour(colors.yellow)
pMenu:setBackgroundColour(colors.blue)

sMenu = ocgui.newMenu(screenX - 10, 9, 11, screenY - 8, true, false, false, true, "left")
sMenu:setBorderTextColour(colors.yellow)
sMenu:setTextColour(colors.yellow)
sMenu:setBackgroundColour(colors.blue)

--mainTextWin - blank window of the same size as other windows
mainTextWin = ocgui.newWindow(1, 4, screenX - 11, screenY -3, true, true, true, true, "left", false)

logoutItem = ocgui.newMenuItem()
logoutItem:newName("Log Out")
logoutItem:newType("quit")
logoutItem:newColour(colors.orange)

getBalItem = ocgui.newMenuItem()
getBalItem:newName("Balance")
getBalItem:newType("getBalance")
getBalItem:newColour(colors.white)

purchaseItem = ocgui.newMenuItem()
purchaseItem:newName("Purchase")
purchaseItem:newType("purchase")
purchaseItem:newColour(colors.white)

sellItem = ocgui.newMenuItem()
sellItem:newName("Sell")
sellItem:newType("sell")
sellItem:newColour(colors.white)

backItem = ocgui.newMenuItem()
backItem:newName("Back")
backItem:newType("back")
backItem:newColour(colors.white)

mainMenu:newOverlay(ocOverlay)

pMenu:newOverlay(pOverlay)
pMenu:newItem(logoutItem)
pMenu:newItem(backItem)

sMenu:newOverlay(sOverlay)
sMenu:newItem(logoutItem)
sMenu:newItem(backItem)

--**********Login Loop**********
login = ocLogin.login()

curPlayer = tostring(login.curPlayer)
acctType = tostring(login.acctType)
corpFlag = tostring(login.flag)
curAcct = tostring(login.account)

if corpFlag == "deposit" then
   mainTextWin:resetData()
   mainTextWin:addData("Corporate Account Chosen - Unable to Access","Changing to Personal Account","","<Press Any Key to Continue>")
   mainTextWin:draw()
   mainTextWin:resetData()
   curAcct = curPlayer
   acctType = "personal"
   local temp = true
   while temp do
      sleep(.1)
      event,id = os.pullEventRaw()
      if event == "key" then
         temp = false
      end
   end
end

mainMenu:newItem(getBalItem)
mainMenu:newItem(purchaseItem)
mainMenu:newItem(sellItem)
mainMenu:newItem(logoutItem)


if debug then
   newLine()
   monitor.write("login loop")
end

rightSidebarBalance:addData(ocSQL.balance(curAcct))

if debug then
   newLine()
   monitor.write("right sidebar balance")
end

purchaseItemsTable = ocSQL.exchangeItems("buy")

if debug then
   newLine()
   monitor.write("purchase items table")
end

purchaseMenuItemList = {}

--create Item Purchase Menu Details
for i=1, #purchaseItemsTable -1 do
   purchase = ocgui.newMenuItem()
   dNameP = tostring(purchaseItemsTable[i].dspName)
   --abbreviate anything before the space to just its first two letters
   if(string.find(dNameP, "%s") ~= nil and string.len(dNameP) > 8) then
      dNameP = string.sub(dNameP, 1, 2).."."..string.sub(dNameP, string.find(dNameP, "%s"), -1)
      dNameP = string.sub(dNameP, 1, 8)
   end
   purchase:newName(dNameP)
   purchase:newType("purchaseItem")
   purchase:newColour(colors.white)
   purchase:setData(getItemTableFromToT(purchaseItemsTable, tostring(purchaseItemsTable[i].rawName), tostring(purchaseItemsTable[i].dmg)))
   table.insert(purchaseMenuItemList, purchase)
end

if debug then
   newLine()
   monitor.write("Purchase Menu Items")
end

sellItemsTable = ocSQL.exchangeItems("sell")

if debug then
   newLine()
   monitor.write("sell items table")
end


sellItems = ocFunc.playerInventory(sensorSide, curPlayer)

sellItemsList = {}


if debug then
   newLine()
   monitor.write("sell items inventory")
   newLine()
   monitor.write(sellItems[1][1].." "..sellItems[2][1])
end

sellMenuItemList = {}

if debug then
   newLine()
   monitor.write("sellMenuItemList table")
end

--create Item Sell Menu Details
for i=1, #sellItems[1] do
   sell = ocgui.newMenuItem()
   if debug then
      newLine()
      monitor.write("newMenuItem")
   end
   item = tostring(sellItems[1][i])
   if debug then
      newLine()
      monitor.write("Item #"..i.." from Inventory")
   end
   for j=1, #sellItemsTable do
      check = tostring(sellItemsTable[j].dspName)
      if debug then
         newLine()
         monitor.write("Item #"..j.." from sql")
      end
      if (item == check) then
         dNameS = check
         if(string.find(dNameS, "%s") ~= nil and string.len(dNameP) > 8) then
            dNameP = string.sub(dNameP, 1, 2).."."..string.sub(dNameP, string.find(dNameP, "%s"), -1)
            dNameP = string.sub(dNameP, 1, 8)
         end
         sell:newName(dNameS)
         sell:newType("sellItem")
         sell:newColour(colors.white)
         sell:setData(getItemTableFromToT(sellItemsTable, tostring(sellItemsTable[j].rawName), tostring(sellItemsTable[j].dmg)))
         table.insert(sellMenuItemList, sell)
         for k=1, #sellMenuItemList do
            sellItemsList[1][k] = sellItems[1][i]
            sellItemsList[2][k] = sellItems[2][i]
         end
      end
   end
end

if debug then
   newLine()
   monitor.write("sell menu items")
end

--Input Item Purchase Details into Menu
for i = 1, #purchaseMenuItemList do
   purchaseMenuWindow:newItem(purchaseMenuItemList[i])
end

if debug then
   newLine()
   monitor.write("purchase items to menu")
end

--Input sellMenuItemList into menu
for i = 1, #sellMenuItemList do
   sellMenuWindow:newItem(sellMenuItemList[i])
end

if debug then
   newLine()
   monitor.write("sell items to menu")
end

choice = ""

while true do
   while (choice == "") do
      ocOverlay:draw()
      rightSidebarStatic:draw()
      rightSidebarBalance:draw()
      mainTextWin:resetData()
      mainTextWin:addData("Welcome to the Con-Am Exchange","","Please select an option from the menu.")
      mainTextWin:draw()
      mainTextWin:resetData()
      if debug then
         newLine()
         monitor.write("mainMenu")
      end

      stype, itemData = mainMenu:draw()

      if debug then
         newLine()
         monitor.write("mainMenu:draw()")
      end

      if stype == "getBalance" then
         if ocFunc.isPlayerPresent(curPlayer, sensorSide) == false then
            mainTextWin:addData("Player "..curPlayer.." no longer here.","Logging out...")
            mainTextWin:draw()
            sleep(1)
            ocFunc.quit()
            break
         end
         balance = ocSQL.balance(curAcct)
         mainTextWin:resetData()
         mainTextWin:addData("Current Bank Balance Is:",balance.." credits","","Press Any Key to Continue")
         mainTextWin:draw()
         local temp = true
         while temp do
            sleep(.1)
            event, id = os.pullEventRaw()
            if event == "key" then
               temp = false
            end
         end
      end

      if stype == "purchase" then
         if debug then
            newLine()
            monitor.write("purchase stype")
         end
         if ocFunc.isPlayerPresent(curPlayer, sensorSide) == false then
            mainTextWin:addData("Player "..curPlayer.." no longer here.","Logging out...")
            mainTextWin:draw()
            sleep(1)
            ocFunc.quit()
            break
         end
         if debug then
            newLine()
            monitor.write("playerPresent")
         end
         choice = "purchase"
         if debug then
            newLine()
            monitor.write("choice = \"purchase\"")
         end
      end

      if stype == "sell" then
         if debug then
            newLine()
            monitor.write("sell stype")
         end
         if ocFunc.isPlayerPresent(curPlayer, sensorSide) == false then
            mainTextWin:addData("Player "..curPlayer.." no longer here.","Logging out...")
            mainTextWin:draw()
            sleep(1)
            ocFunc.quit()
            break
         end
         choice = "sell"
         if debug then
            newLine()
            monitor.write("choice = \"sell\"")
         end

      end

      if stype == "quit" then
         ocFunc.quit()
         break
      end

   end

   while (choice == "purchase") do
      if debug then
         monitor.write("choice == \"purchase\"")
         newLine()
      end
      term.clear()
      pOverlay:draw()
      rightSidebarStatic:draw()
      rightSidebarBalance:draw()
      mainMenuWindow:draw()
      mainTextWin:resetData()
      mainTextWin:addData("Welcome to the Con-Am Exchange","","Purchase Interface","","Please select an item to purchase","from the menu.")
      mainTextWin:draw()
      mainTextWin:resetData()
      if debug then
         newLine()
         monitor.write("purchase menu setup")
      end

      stype, itemData = pMenu:draw()
      if debug then
         newLine()
         monitor.write("pMenu:draw()")
      end
  if stype == "purchaseItem" then
         base = tonumber(itemData.overridePrice)
         euExchange = tonumber(ocSQL.euExchange)
         markup = tonumber(ocSQL.itemPriceMarkup())
         basePrice = base*euExchange*markup

         --when we setup item price changing on buy/sell     
         --storeInv = itemData.storeInv
         --storeInvMid = itemData.storeInvMid
         --storeInvMod = storeInvMid/storeInv
         --price = basePrice*storeInvMod

         price = basePrice

         if (price < 1) then
            price = 1
         end

         mainTextWin:addData("Note: All sales deduct directly from","your bank account.","",tostring(itemData.dspName)..":")
         mainTextWin:addData("Value Per Unit: "..price.." credits","Value per Stack ("..itemData.maxStackSize.."): "..tostring(price * tonumber(itemData.maxStackSize)).."c")
         MainTextWin:draw()
         term.setCursorPos(2, 12)
         write("Amount to Buy: ")
         local buyAmt = read()
         if ocFunc.isPlayerPresent(curPlayer, sensorSide) == false then
            mainTextWin:addData("Player "..curPlayer.." no longer here.","Logging out...")
            mainTextWin:draw()
            sleep(1)
            ocFunc.quit()
            break
         end
         term.setCursorPos(2, 13)
         if(tonumber(buyAmt) == nil) then
            term.setTextColour(colors.red)
            write(buyAmt.." is not a valid number")
            term.setTextColour(colors.red)
            sleep(2)
         elseif (tonumber(balance) == nil) then
            term.setTextColour(colors.red)
            write("Error getting balance. Contact an Admiral")
            term.setTextColour(colors.white)
            sleep(2)
         elseif(tonumber(buyAmt * price) > tonumber(balance)) then
            term.setTextColour(colors.red)
            write("Insufficient Funds")
            term.setTextColour(colors.white)
            sleep(2)
         elseif (tonumber(buyAmt) <= 0) then
            term.setTextColour(colors.red)
            write("Must input a positive number")
            term.setTextColour(colors.white)
            sleep(2)
         else -- theck that player has space
            local numSlotsReq = ocFunc.getSpaceReq(tonumber(buyAmt), tonumber(itemData.maxStackSize))
            local hasSpace = ocFunc.hasSlotsRequired(sensorSide, curPlayer, numSlotsReq)
            if (hasSpace == false) then
               term.setTextColour(colors.red)
               write("Not Enough Inventory Space ("..numSlotsReq.." slots)")
               term.setTextColour(colors.white)
               sleep(2)
            else --player has space and funds
               cost = (buyAmt * price)
               ocSQL.transfer(curAcct, "corpConAm", cost)
               --do/gives
               --ocFunc.giveItems(playerName, cmdBlockSide, itemId, itemMeta, itemQty, stackSize)
               ocFunc.giveItems(curPlayer, cmdBlockSide, tostring(itemData.blockId), tostring(itemData.dmg), tonumber(buyAmt), tonumber(itemData.maxStackSize))
               term.setTextColour(colors.lime)
               write("Purchase Successful!")
               term.setCursorPos(2, 14)
               write("Press Any Key To Continue")
               term = true
               while temp do
                  sleep(.1)
                  event, id = os.pullEventRaw()
                  if (event == "key") then
                     temp = false
                  end
               end
            end
         end
         balance = ocFunc.balance(curAcct)
      end

      if stype == "quit" then
         ocFunc.quit()
         break
      end

      if stype == "back" then
         choice = ""
      end      

   end

   while (choice == "sell") do
      if debug then
         newLine()
         monitor.write("choice == \"sell\"")
      end
      term.clear()
      ocOverlay:draw()
      rightSidebarStatic:draw()
      rightSidebarBalance:draw()
      mainMenuWindow:draw()
      mainTextWin:resetData()
      mainTextWin:addData("Welcome to the Con-Am Exchange","","Sales Interface","","Please select an item to sell","from the menu.","","Sales are for all of chosen","","item in inventory.")
      mainTextWin:draw()
      mainTextWin:resetData()
      if debug then
         newLine()
         monitor.write("sell Menu Setup")
      end

      stype, itemData = sMenu:draw()
      if debug then
         newLine()
         monitor.write("sMenu:draw()")
      end
      if stype == "sellItem" then
         base = tonumber(itemData.overridePrice)
         for i=1, #sellItemsList[1] do
            if sellItemsList[1][i] == itemData.dspName then
               itemAmt = sellItemsList[2][i]
            end
         end

        --when we setup item price changing on buy/sell     
         --storeInv = itemData.storeInv
         --storeInvMid = itemData.storeInvMid
         --storeInvMod = storeInvMid/storeInv
         --price = base*storeInvMod

         price = base

         if (price < 1) then
            price = 1
         end

         mainTextWin:addData("Note: all sales are added directly to","your bank account","",tostring(itemData.dspName..":"))
         mainTextWin:addData("Value Per Unit: "..price.."c", "","for a total of "..(price*itemAmt).."c","","'Q' to quit, any other key to continue")
         mainTextWin:draw()
         mainTextWin:resetData()
         temp = true
         quit = false
         while temp do
            sleep(.1)
            event, id = os.pullEventRaw()
            if id == "81" then
               quit = true
               temp = false
            elseif event == "key" then
               temp = false
            end
         end
         mainTextWin:resetData()
         if quit == false then
            ocFunc.clearSoldItems(curPlayer, cmdBlockSide, tostring(itemData.blockId), tostring(itemData.dmg))
            ocSQL.withdraw("corpConAm", (sellAmt * price))
            ocSQL.deposit(curAcct, (sellAmt * price))
            mainTextWin:setTextColour(colors.lime)
            mainTextWin:addData("Sale Successful!","","<Press Any Key To Continue>")
            temp = true
            while temp do
               sleep(.1)
               event, id = os.pullEventRaw()
               if (event == "key") then
                  temp = false
               end
            end
         end
         balance = ocFunc.balance(curAcct)
      end

      if stype == "quit" then
         ocFunc.quit()
         break
      end

      if stype == "back" then
         choice = ""
      end

   end
end

Bomb Bloke #2
Posted 18 January 2014 - 06:18 PM
Per the notes in this thread, this is generally caused by excessive function calls - a loop where functions keep getting called but aren't allowed to end (eg because they call more functions which call more functions etc…) eventually triggers an overflow.

At a glance, I can't see anything like that in this code.
awsmazinggenius #3
Posted 18 January 2014 - 06:31 PM
Could you briefly describe what the code is for? It would help me help you.
zeronoashaen #4
Posted 27 January 2014 - 12:22 AM
This code is for my server Outlandcraft. it is used for an exchange where players can buy/sell items from/to the "Company". I have fixed the program all except getting the selling portion working. I started a new thread for that here: http://www.computercraft.info/forums2/index.php?/topic/16862-problem-with-nested-for-loop/