I had to register to say thank you for this excellent script. I was really excited to find it and have been really enjoying using it.
I have a few quick bits of feedback:
* The date_time variable is slightly wrong. You've used a capital M for minutes in the date string where you should have a small m for month:
line 188:
- DATE_TIME=$(date +%Y-%M-%d-%H:%M:%S)
+ DATE_TIME=$(date +%Y-%m-%d-%H:%M:%S)
Obviously this isn't critical, but is an easy enough fix to be worthwhile.
* The map function fails silently if the required folders don't already exist. The "maps" folder is made, but if the underlying "WORLDNAME" folders aren't already there, nothing happens. I manually made the folders and it's fine now; not sure if this is a quirk on my system or an oversight....
* Would you consider adding a function to the backup routine that purges existing backups that are x days old, or only keeping the most recent x number of backups? I know this is a really non-trivial change, but would be super convenient....
Also, I wrote a quick and dirty command that uses Ubuntu's native notification system to alert me when players log in or send messages (my server is just for myself and two RL friends, so it's not overwhelming to plug into all this activity and there's utility in knowing when my friends sign in). I'd love to be able to incorporate this into your service so it starts (and stops) with the server itself, but I've had no luck at all. I apologize that this is more of a vanity request, but it's possible someone else might find it useful (and I banged my head against getting it work for entirely too long):
You will instantly see how this works because you are a genius, but for anyone (like me) following along at home, I'll explain what happens there:
"tail -f" follows the server log, which gets you easy access to login/logout and all chat console messages
"grep -v "<username>"" will filter out lines from the log that you type into the chat console (becomes overwhelming without this and the messages are not important to see in the notification area)
"while read line" simple loop to send the notification for each line as it comes in
"notify-send" is the Ubuntu notification bubbles (see here for details)
"${line:20}" this just trims the line in question of the first 20 characters to remove the timestamps when popping up the notification. Fancier sed regexps could net you more or less information, but this works well for me.
"osd-icon.png" is whatever you want the icon to be inside the bubble. I used the 32px one from here and it's an excellent fit.
Curiously, this works when pasted into the terminal directly (with hardcoded values for the paths, natch), but fails when called as a bash script. Apparently I am full of fail.
I'm sure this isn't useful widely enough to warrant inclusion in your script, but if you could provide some guidance on how to hack it in, I'd be super grateful.... I've tried a number of ways, but each of them broke the service.
Anyway, thanks so much for posting this in the first place. I'm really surprised there aren't more comments here; you did a great job.
I had to register to say thank you for this excellent script. I was really excited to find it and have been really enjoying using it.
I have a few quick bits of feedback:
Nice, I'm really glad that someone else is finding this script useful. And thank you for the feedback, I really appreciate it.
Quote from rad_ »
* The date_time variable is slightly wrong. You've used a capital M for minutes in the date string where you should have a small m for month:
line 188:
- DATE_TIME=$(date +%Y-%M-%d-%H:%M:%S)
+ DATE_TIME=$(date +%Y-%m-%d-%H:%M:%S)
Obviously this isn't critical, but is an easy enough fix to be worthwhile.
I noticed this myself yesterday and quietly fixed it. I also added in a %s (seconds since 01/01/1970) in front of the year to make cleaning up old backups easier. The rest of the filename is purely to make the user's life easier in case they need to restore a backup.
edit: I'm removing the %s, and I'm renaming backup files so that I can easily support incremental backups in addition to full backups in the future. I figured out a cleaner way to remove old files than trying to calculate how old files are using a difference in seconds from an epoch method. I'll update the main post here in a few minutes with your suggested change. I'll work on incremental backups as I have time. This code is a work in progress, and is mostly untested so for the next few days we'll just have to rely on my interpretation of the man pages being correct (my tests worked, but I only had one backup to play with). I really need to figure out how to use cron so that I can a) get it to do all the hard work (remembering to do ****) for me, and :cool.gif: integrate it with the script to make it easy for you guys.
Quote from rad_ »
* The map function fails silently if the required folders don't already exist. The "maps" folder is made, but if the underlying "WORLDNAME" folders aren't already there, nothing happens. I manually made the folders and it's fine now; not sure if this is a quirk on my system or an oversight....
Hmm, I'll look into fixing this. I want this script to build up its environment properly if it isn't already, including building the appropriate directory structure.
edit: You are completely right, total oversight here. Fixed, directories are now created when needed. The version of c10t that I was originally running wouldn't shut-up when I told it to (-s option), so I had its output routed to /dev/null, explaining the lack of error message when you first ran the map function. I checked today's version of c10t (the script can now auto update), and it no longer has that problem, so I removed the output routing to allow any errors to flow through.
Quote from rad_ »
* Would you consider adding a function to the backup routine that purges existing backups that are x days old, or only keeping the most recent x number of backups? I know this is a really non-trivial change, but would be super convenient....
Definitely planned, in fact it is next on my list of features to add in. I'm also looking at auto-injecting the script into a crontab so that you can schedule backups, but I've never played around with it before so it will be a fun learning experience.
edit: backup files now have a duration until they expire that can be changed in the beginning of the script. See above.
Quote from rad_ »
Also, I wrote a quick and dirty command that uses Ubuntu's native notification system to alert me when players log in or send messages (my server is just for myself and two RL friends, so it's not overwhelming to plug into all this activity and there's utility in knowing when my friends sign in). I'd love to be able to incorporate this into your service so it starts (and stops) with the server itself, but I've had no luck at all. I apologize that this is more of a vanity request, but it's possible someone else might find it useful (and I banged my head against getting it work for entirely too long):
You will instantly see how this works because you are a genius, but for anyone (like me) following along at home, I'll explain what happens there:
"tail -f" follows the server log, which gets you easy access to login/logout and all chat console messages
"grep -v "<username>"" will filter out lines from the log that you type into the chat console (becomes overwhelming without this and the messages are not important to see in the notification area)
"while read line" simple loop to send the notification for each line as it comes in
"notify-send" is the Ubuntu notification bubbles (see here for details)
"${line:20}" this just trims the line in question of the first 20 characters to remove the timestamps when popping up the notification. Fancier sed regexps could net you more or less information, but this works well for me.
"osd-icon.png" is whatever you want the icon to be inside the bubble. I used the 32px one from here and it's an excellent fit.
Curiously, this works when pasted into the terminal directly (with hardcoded values for the paths, natch), but fails when called as a bash script. Apparently I am full of fail.
I'm sure this isn't useful widely enough to warrant inclusion in your script, but if you could provide some guidance on how to hack it in, I'd be super grateful.... I've tried a number of ways, but each of them broke the service.
This is cool. I've been thinking of adding in some log parsing. Being able to tie into libnotify would be a cool option, I'll see what it would take to add it in.
Quote from rad_ »
Anyway, thanks so much for posting this in the first place. I'm really surprised there aren't more comments here; you did a great job.
Thank you for the feedback! I'm really happy to see that it is working for other people.
Your recent changes are all really wonderful. Great work.
I like the new send command, too. Coupled with the new "list" server command, there's some potentially really useful information to be had here. From what I can tell, though, the server only outputs the connected players to the log, so log parsing is still needed to really make sense of the info.
I added a quick couple lines to the "status" case in your script since I've got my hacky log notifications anyway, so I can see the results of the list at least. Doesn't seem to be an elegant way to pull this off for real, though. You'd have to parse the log completely and have a test case for when no one is connected (the console just returns nothing rather than a message about no one being connected), and then do heavy lifting on the log to output the names into the terminal into a list of their own where the "status" command was likely run. So close, and yet....
Ran into a new bug today. I ran "update" through your script, but something failed silently. Server said it restarted (I think.... If there was an error, it didn't stick out), so I left it alone. Tried to log in a few hours later and nothing was connecting.
Turns out the server.jar was 0b. Ran "update" again and it actually pulled the new file and now everything is great again.
Two things, then:
* Update routine should check for http errors and/or make sure the server software isn't 0 bytes. If an error like that occurs, print a message and don't attempt to restart the server (maybe?).
* Server "start" routine could either have a quick error case for problems with the file itself and then try to update it (like on first run, but for errors like this), or at least print a message. With my 0 byte server.jar it would just say "starting the server" and then nothing else would happen. It wasn't too hard to find the problem, so this isn't a big deal, but it occurred to me that calling out the file as the problem would be somewhat helpful (though maybe not worth the extra weight in the code?), and that in doing so, the redownload could actually be cleverly automated....
Your recent changes are all really wonderful. Great work.
Thanks!
Quote from rad_ »
I like the new send command, too. Coupled with the new "list" server command, there's some potentially really useful information to be had here. From what I can tell, though, the server only outputs the connected players to the log, so log parsing is still needed to really make sense of the info.
I've been looking at the logs, and what I could do to them to make the information more available. First off, I think I'm going to separate the logs into daily files, then have a cleanup routine similar to backup that will remove old logs. I also plan on having a separate file in the world directory that will keep track of logged in users, that will be updated by catching the login and logout statements from the server (and if available and wanted, notify the desktop user of these events with libnotify as you requested). I'm also thinking of tracking user issued server commands, in particular the give command. I think it might be kind of neat to see a) who is using the command, and :cool.gif: what they are using it for.
Quote from rad_ »
Ran into a new bug today. I ran "update" through your script, but something failed silently. Server said it restarted (I think.... If there was an error, it didn't stick out), so I left it alone. Tried to log in a few hours later and nothing was connecting.
Turns out the server.jar was 0b. Ran "update" again and it actually pulled the new file and now everything is great again.
I've put some effort into handling user errors correctly, but I haven't even thought of dealing with other sources of errors, such as you just ran into. I'll take a closer look at the program and make sure that it catches more of these kind of errors. Right now the script is deleting the old server.jar before trying to download the new one, I should probably keep it around until after the download finishes in case there is such an error.
If I don't spend too much time playing Minecraft over the weekend, I'll try to get some of the logging stuff coded up. At the very least I'll take a look at error checking and get a new release out soon. I've also been reading some rsync tutorials, and it seems like a more logical way to do incremental backups than tar. I think I'll leave tar in the full backup routine, and set up some kind of rotating rsync for the incremental backups.
edit: The most recent version has some simple error detection on the wget and screen commands, if they fail it will now print an error message. When updating the server it will restore a backup if available then stop execution, when updating c10t it will just print its message then stop execution. If this method fails to detect the 0kb file issue that you saw, I might be able to add in some form of md5sum checking of the server jar or something (does Notch post this info??).
## Line 387
# Show the status of each world requested.
for WORLD in $WORLDS; do
printf " $WORLD > status: "
if [ $(serverRunning $WORLD) = 1 ]; then
printf "running.\n"
sendCommand $WORLD "list"
printf " $WORLD > connected players: "
PLAYERLIST=`eval tail -n1 $WORLDS_LOCATION/$WORLD/server.log | grep --line-buffered "players:"`
if [ ${#PLAYERLIST} == "46" ]; then
printf "none\n"
else
printf "${PLAYERLIST:46}\n"
fi
else
printf "not running.\n"
fi
done
Instead of writing the log in/out states to a file, you can just send the list command and immediately tail the log for the connected players. (This will report "none" if something else is concurrently logged and the last line isn't the connected players list. Not sure how likely this is. Tried implementing a check for zero length on $PLAYERLIST and running the list/tail again if it was, but didn't want to structure that into a loop, so just pulled the check out....)
One benefit from doing it the way you wanted (current list of logged in players in a separate file), though, is that having that info handy would make listening for chats in the log easier (grep "<$1>|<$2>|..." -> though I'm not sure how best to structure that code on account of ther ebeing a variable number of usernames).... But it sounds a lot more complicated.
The above works great on my end, but I had to change your script to execute as BASH instead of just SH in line 1. Apparently SH doesn't support the substring syntax and I couldn't find a reference anywhere for relevant operations. No noticeable impact elsewhere for the change, but I'm a little wary. Did you use SH for any explicit reasons?
Also, this means I can probably put the libnotify stuff from before in the script proper (inelegant though it is), since the trim function was the likely cause of the errors there, too. Will have to roll up my sleeves and more properly parse the log to keep notifications down....
Strike that about the chats. Potentially better idea:
1. Parse log for "<*>" lines, strip timestamp, write to chat.log file as they come in
2. Follow chat.log and grep -v yourself (hardcoded variable in script? read from admin file?)
3. libnotify the lines that are left
No need to follow log in/out, and seems like much simpler logic to structure. What do you think?
For some reason I couldn't get the script from pastebin without having ^M's at the end of each line. So the script would not run. Maybe I don't understand pastebin.
So, just in case anyone else is having this problem, running (for example if you call your download file pesky-ctrl-m-bah ):
sed 's/'"$(printf '\015')"'$//g' pesky-ctrl-m-bah >>minecraft_server
produces the file minecraft_server with no pesky ^M's
dM
I've never had a problem with ^M getting inserted into things with Pastebin, but I've been thinking of changing hosts anyway. I would like to include in the update routine a method to update the script, but the address for Pastebin changes with every update. Does Sourceforge sound reasonable? I'm using it for a couple of other projects, it might work here too.
BTW: Pastebin has a download link on the upper right hand side of the page. I'm not sure if that is what is giving you the problem or not, but it seems to work for me.
Apparently SH doesn't support the substring syntax and I couldn't find a reference anywhere for relevant operations. No noticeable impact elsewhere for the change, but I'm a little wary. Did you use SH for any explicit reasons?
SH is just a soft link to your default shell environment. User shells are often Bash by default, but on Debian and Ubuntu based distros, they are switching over to using Dash as the default shell for root. Since I want this script to be as portable as possible, I've used only the subset of the shell language that is supported by almost all shell environments, and Dash is as limited as they come. You can do pretty much anything you want to do in Dash without resorting to using a Bash specific extension with very little effort as I've so far found. Feel free to change the shabang line to Bash if you want, it will make little difference.
Quote from rad_ »
Strike that about the chats. Potentially better idea:
1. Parse log for "<*>" lines, strip timestamp, write to chat.log file as they come in
2. Follow chat.log and grep -v yourself (hardcoded variable in script? read from admin file?)
3. libnotify the lines that are left
No need to follow log in/out, and seems like much simpler logic to structure. What do you think?
I'm still working on the code, but I should be able to track users logging in and out by searching for the following patterns:
Logins:
<date> <time> [INFO] <user> [/<ip address>] logged in with an entity id <entity id>
Logouts:
<date> <time> [INFO] <user> lost connection: <reason>
I also plan on capturing any command response data issued by the send command, and returning the text to the console that issued the command. This might be tricky, but if I can get it to work, I'll be looking for the following pattern:
<date> <time> [INFO] [CONSOLE] <message>
I'm still quite a ways off from having anything usable, I'll try to get something posted this weekend. I've been working on my minecart station quite a bit lately, and in fact hit a major milestone with it today: the minecart request button finally works. Four holding bays, two levels of tracks, and two levels of logic circuits... I never thought I would ever use my logic circuit classes in college, but they are surprisingly coming in handy at playing this game. Ha. Programming in a high level language like Perl, Java, or even shell script is light-years easier than dealing with 1's, 0's, and some NOR gates. Debugging this stuff is hell! I've gained some new respect for the world's Electrical Engineers, seriously.
You can do pretty much anything you want to do in Dash without resorting to using a Bash specific extension with very little effort as I've so far found.
According to this, the replacement for my simple Bash substring operation is to use sed or awk, which I couldn't make work for the life of me the first time around. I will bow out and just wait to see what you come up with....
The only problem I have is that the c10t function only works for worlds called "world", as this is hardcoded:
su -c "$C10T_BIN -s -w $WORLDS_LOCATION/$1/world -o $MAPS_LOCATION/$1/surface.png" $USER_NAME
For a world called "beta" for example, the world files actually are in $WORLDS_LOCATION/beta/beta, not $WORLDS_LOCATION/beta/world. Therefore the lines should be as follows:
su -c "$C10T_BIN -s -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/surface.png" $USER_NAME
I've thought of changing the code so that Minecraft and the script are using the same name for the world (right now Minecraft only sees the world name 'world' regardless of what the script thinks the world name is), but the change needs to happen in a few places. For instance, when first starting the server, it checks to make sure that the server.properties file exists, and it defaults to using a world name of 'world' if it doesn't. As far as I know, the only reason you should actually hit an issue here is if you started using this script with a previously running server, and in that case you would have to modify your config anyway. At this point, I'm a bit loathe to change it, but it is a probably a good idea in the long run. The problem is, this script has an existing user-base, so I'll either have to add code to update the old way to the new way of doing things, or break old configurations. Neither option is ideal, hence my reluctance to do this right now. =/
Edit: I went ahead and made this change. The script should hopefully update any old configurations.
Thanks for the great script. I have it running (mainly).. but I had a few issues.
My system: Ubuntu 9.10. I had the other script running with dated backups as a bash script if that makes a difference.
1. wont' download new c10t bin. (can't find an error)
But I just placed the bin in the correct dir
2. Backup places a oddly named .gz file into the correct dir. I take it that my system doesn't like the date code you use.
Also it looks like i have my working dirs a bit different. I tried to edit it but maybe there is something missing. (ie. It seems to me that your worlds are in /minecraft_server/worlds/world/world
Any suggestions would be greatly appreciated.
Cheers,
d
Thanks for the great script. I have it running (mainly).. but I had a few issues.
My system: Ubuntu 9.10. I had the other script running with dated backups as a bash script if that makes a difference.
1. wont' download new c10t bin. (can't find an error)
But I just placed the bin in the correct dir
2. Backup places a oddly named .gz file into the correct dir. I take it that my system doesn't like the date code you use.
Also it looks like i have my working dirs a bit different. I tried to edit it but maybe there is something missing. (ie. It seems to me that your worlds are in /minecraft_server/worlds/world/world
Any suggestions would be greatly appreciated.
Cheers,
d
Try the most recent version of the script and let me know if you are still having the same problems. I've made a few changes that might clean things up for you.
If you are still having issues, let me know what the output from the following commands are:
uname -m
date +%Y-%m-%d-%H:%M:%S
The current code tells Minecraft to load the world files located in /home/minecraft/worlds/alpha/alpha if the world's name is 'alpha'. The first alpha denotes the world name that the script sees, the second is actually the level-name in the server.properties file. Old versions of the script told Minecraft that the level-name was 'world', regardless of what the script thought the world name was (ie /home/minecraft/worlds/alpha/world), but I found this slightly confusing myself and was not surprised to see issues in this thread. I just changed it so that the world name that the script sees is the same as the level-name that Minecraft sees. The double alpha in the directory name is still required to keep the Minecraft server files for each world separate from one another easily (and keep the server itself happy). I hope this explains your last question.
Thanks for replying. It didn't make a difference. I am not sure what I am doing wrong here. The only change I have made is the folders. I found that kept everything in a slightly different structure. (If you think that is an issue I can explain it)
uname -m
i686
date +%Y-%m-%d-%H:%M:%S
2011-01-18-20:30:39
Anything else I can try? I guess there will be a web interface for this sort of thing soon. (bukket? or something). But I like the ability to SSH in and make these simple changes...
Thanks for replying. It didn't make a difference. I am not sure what I am doing wrong here. The only change I have made is the folders. I found that kept everything in a slightly different structure. (If you think that is an issue I can explain it)
uname -m
i686
date +%Y-%m-%d-%H:%M:%S
2011-01-18-20:30:39
Anything else I can try? I guess there will be a web interface for this sort of thing soon. (bukket? or something). But I like the ability to SSH in and make these simple changes...
Thanks again,
d
Ok, that explains the issue with updating c10t. My box returns 'x86_64' with the uname command, and I assumed that 32 bit boxes returned 'x86'. I'll make some changes to fix this one.
As far as the issue with the backups, give me a directory listing or an example of the failed backup names. It should look like 'fullBackup-alpha-2011-01-12-21:41:55.tar.gz'. Your date command appears to function the same as mine, so I'm not sure what's going on here. Maybe I should simplify the names by removing the time stamp, although I like being able to have multiple backups in a single day. I'll try to think of a possible work around while I wait for your reply on this one.
I posted a new version of the script that should, hopefully, fix the c10t update issue. Let me know if it doesn't (you can delete the old directory and see if it downloads a new one).
The backup issue confuses me. First off, are the backups looking like that on your Ubuntu box? Windows? What file system is being used? Can you give me a full directory listing of the backup directory?
ls -la /media/data/Share/1mc_backup
My guess is it has something to do with the colons ":" in the file name, and that you are writing to a NTFS file system or something else that doesn't like that. I'll work out a better naming system for the backup files (maybe instead of the time, I'll just add a -1 -2 for multiple backups in the same day).
What did you change in the most recent script? I have to edit each dir line for every new one. :smile.gif: Would be quicker to just update the line(s) that you updated.
I will take a look thru it though. I might see the ones changed for c10t.
Thanks again for you help.
---Edit---
Ok, The c10t worked. Updated no problem.. I deleted the /c10t and everything. Thanks !!
Minecraft Server Control Script (MSCS) is a server-management script for UNIX and Linux powered Minecraft servers.
Features include:
See the Github page for downloads and up to date documentation.
Enjoy,
Sandain
I have a few quick bits of feedback:
* The date_time variable is slightly wrong. You've used a capital M for minutes in the date string where you should have a small m for month:
Obviously this isn't critical, but is an easy enough fix to be worthwhile.
* The map function fails silently if the required folders don't already exist. The "maps" folder is made, but if the underlying "WORLDNAME" folders aren't already there, nothing happens. I manually made the folders and it's fine now; not sure if this is a quirk on my system or an oversight....
* Would you consider adding a function to the backup routine that purges existing backups that are x days old, or only keeping the most recent x number of backups? I know this is a really non-trivial change, but would be super convenient....
Also, I wrote a quick and dirty command that uses Ubuntu's native notification system to alert me when players log in or send messages (my server is just for myself and two RL friends, so it's not overwhelming to plug into all this activity and there's utility in knowing when my friends sign in). I'd love to be able to incorporate this into your service so it starts (and stops) with the server itself, but I've had no luck at all. I apologize that this is more of a vanity request, but it's possible someone else might find it useful (and I banged my head against getting it work for entirely too long):
You will instantly see how this works because you are a genius, but for anyone (like me) following along at home, I'll explain what happens there:
"tail -f" follows the server log, which gets you easy access to login/logout and all chat console messages
"grep -v "<username>"" will filter out lines from the log that you type into the chat console (becomes overwhelming without this and the messages are not important to see in the notification area)
"while read line" simple loop to send the notification for each line as it comes in
"notify-send" is the Ubuntu notification bubbles (see here for details)
"${line:20}" this just trims the line in question of the first 20 characters to remove the timestamps when popping up the notification. Fancier sed regexps could net you more or less information, but this works well for me.
"osd-icon.png" is whatever you want the icon to be inside the bubble. I used the 32px one from here and it's an excellent fit.
Curiously, this works when pasted into the terminal directly (with hardcoded values for the paths, natch), but fails when called as a bash script. Apparently I am full of fail.
I'm sure this isn't useful widely enough to warrant inclusion in your script, but if you could provide some guidance on how to hack it in, I'd be super grateful.... I've tried a number of ways, but each of them broke the service.
Anyway, thanks so much for posting this in the first place. I'm really surprised there aren't more comments here; you did a great job.
Nice, I'm really glad that someone else is finding this script useful. And thank you for the feedback, I really appreciate it.
I noticed this myself yesterday and quietly fixed it. I also added in a %s (seconds since 01/01/1970) in front of the year to make cleaning up old backups easier. The rest of the filename is purely to make the user's life easier in case they need to restore a backup.
edit: I'm removing the %s, and I'm renaming backup files so that I can easily support incremental backups in addition to full backups in the future. I figured out a cleaner way to remove old files than trying to calculate how old files are using a difference in seconds from an epoch method. I'll update the main post here in a few minutes with your suggested change. I'll work on incremental backups as I have time. This code is a work in progress, and is mostly untested so for the next few days we'll just have to rely on my interpretation of the man pages being correct (my tests worked, but I only had one backup to play with). I really need to figure out how to use cron so that I can a) get it to do all the hard work (remembering to do ****) for me, and :cool.gif: integrate it with the script to make it easy for you guys.
Hmm, I'll look into fixing this. I want this script to build up its environment properly if it isn't already, including building the appropriate directory structure.
edit: You are completely right, total oversight here. Fixed, directories are now created when needed. The version of c10t that I was originally running wouldn't shut-up when I told it to (-s option), so I had its output routed to /dev/null, explaining the lack of error message when you first ran the map function. I checked today's version of c10t (the script can now auto update), and it no longer has that problem, so I removed the output routing to allow any errors to flow through.
Definitely planned, in fact it is next on my list of features to add in. I'm also looking at auto-injecting the script into a crontab so that you can schedule backups, but I've never played around with it before so it will be a fun learning experience.
edit: backup files now have a duration until they expire that can be changed in the beginning of the script. See above.
This is cool. I've been thinking of adding in some log parsing. Being able to tie into libnotify would be a cool option, I'll see what it would take to add it in.
Thank you for the feedback! I'm really happy to see that it is working for other people.
I like the new send command, too. Coupled with the new "list" server command, there's some potentially really useful information to be had here. From what I can tell, though, the server only outputs the connected players to the log, so log parsing is still needed to really make sense of the info.
I added a quick couple lines to the "status" case in your script since I've got my hacky log notifications anyway, so I can see the results of the list at least. Doesn't seem to be an elegant way to pull this off for real, though. You'd have to parse the log completely and have a test case for when no one is connected (the console just returns nothing rather than a message about no one being connected), and then do heavy lifting on the log to output the names into the terminal into a list of their own where the "status" command was likely run. So close, and yet....
Turns out the server.jar was 0b. Ran "update" again and it actually pulled the new file and now everything is great again.
Two things, then:
* Update routine should check for http errors and/or make sure the server software isn't 0 bytes. If an error like that occurs, print a message and don't attempt to restart the server (maybe?).
* Server "start" routine could either have a quick error case for problems with the file itself and then try to update it (like on first run, but for errors like this), or at least print a message. With my 0 byte server.jar it would just say "starting the server" and then nothing else would happen. It wasn't too hard to find the problem, so this isn't a big deal, but it occurred to me that calling out the file as the problem would be somewhat helpful (though maybe not worth the extra weight in the code?), and that in doing so, the redownload could actually be cleverly automated....
Thanks!
I've been looking at the logs, and what I could do to them to make the information more available. First off, I think I'm going to separate the logs into daily files, then have a cleanup routine similar to backup that will remove old logs. I also plan on having a separate file in the world directory that will keep track of logged in users, that will be updated by catching the login and logout statements from the server (and if available and wanted, notify the desktop user of these events with libnotify as you requested). I'm also thinking of tracking user issued server commands, in particular the give command. I think it might be kind of neat to see a) who is using the command, and :cool.gif: what they are using it for.
I've put some effort into handling user errors correctly, but I haven't even thought of dealing with other sources of errors, such as you just ran into. I'll take a closer look at the program and make sure that it catches more of these kind of errors. Right now the script is deleting the old server.jar before trying to download the new one, I should probably keep it around until after the download finishes in case there is such an error.
If I don't spend too much time playing Minecraft over the weekend, I'll try to get some of the logging stuff coded up. At the very least I'll take a look at error checking and get a new release out soon. I've also been reading some rsync tutorials, and it seems like a more logical way to do incremental backups than tar. I think I'll leave tar in the full backup routine, and set up some kind of rotating rsync for the incremental backups.
edit: The most recent version has some simple error detection on the wget and screen commands, if they fail it will now print an error message. When updating the server it will restore a backup if available then stop execution, when updating c10t it will just print its message then stop execution. If this method fails to detect the 0kb file issue that you saw, I might be able to add in some form of md5sum checking of the server jar or something (does Notch post this info??).
Instead of writing the log in/out states to a file, you can just send the list command and immediately tail the log for the connected players. (This will report "none" if something else is concurrently logged and the last line isn't the connected players list. Not sure how likely this is. Tried implementing a check for zero length on $PLAYERLIST and running the list/tail again if it was, but didn't want to structure that into a loop, so just pulled the check out....)
One benefit from doing it the way you wanted (current list of logged in players in a separate file), though, is that having that info handy would make listening for chats in the log easier (grep "<$1>|<$2>|..." -> though I'm not sure how best to structure that code on account of ther ebeing a variable number of usernames).... But it sounds a lot more complicated.
The above works great on my end, but I had to change your script to execute as BASH instead of just SH in line 1. Apparently SH doesn't support the substring syntax and I couldn't find a reference anywhere for relevant operations. No noticeable impact elsewhere for the change, but I'm a little wary. Did you use SH for any explicit reasons?
Also, this means I can probably put the libnotify stuff from before in the script proper (inelegant though it is), since the trim function was the likely cause of the errors there, too. Will have to roll up my sleeves and more properly parse the log to keep notifications down....
As ever: thank you and you rock.
1. Parse log for "<*>" lines, strip timestamp, write to chat.log file as they come in
2. Follow chat.log and grep -v yourself (hardcoded variable in script? read from admin file?)
3. libnotify the lines that are left
No need to follow log in/out, and seems like much simpler logic to structure. What do you think?
I've never had a problem with ^M getting inserted into things with Pastebin, but I've been thinking of changing hosts anyway. I would like to include in the update routine a method to update the script, but the address for Pastebin changes with every update. Does Sourceforge sound reasonable? I'm using it for a couple of other projects, it might work here too.
BTW: Pastebin has a download link on the upper right hand side of the page. I'm not sure if that is what is giving you the problem or not, but it seems to work for me.
SH is just a soft link to your default shell environment. User shells are often Bash by default, but on Debian and Ubuntu based distros, they are switching over to using Dash as the default shell for root. Since I want this script to be as portable as possible, I've used only the subset of the shell language that is supported by almost all shell environments, and Dash is as limited as they come. You can do pretty much anything you want to do in Dash without resorting to using a Bash specific extension with very little effort as I've so far found. Feel free to change the shabang line to Bash if you want, it will make little difference.
I'm still working on the code, but I should be able to track users logging in and out by searching for the following patterns:
I also plan on capturing any command response data issued by the send command, and returning the text to the console that issued the command. This might be tricky, but if I can get it to work, I'll be looking for the following pattern:
I'm still quite a ways off from having anything usable, I'll try to get something posted this weekend. I've been working on my minecart station quite a bit lately, and in fact hit a major milestone with it today: the minecart request button finally works. Four holding bays, two levels of tracks, and two levels of logic circuits... I never thought I would ever use my logic circuit classes in college, but they are surprisingly coming in handy at playing this game. Ha. Programming in a high level language like Perl, Java, or even shell script is light-years easier than dealing with 1's, 0's, and some NOR gates. Debugging this stuff is hell! I've gained some new respect for the world's Electrical Engineers, seriously.
According to this, the replacement for my simple Bash substring operation is to use sed or awk, which I couldn't make work for the life of me the first time around. I will bow out and just wait to see what you come up with....
Congrats on the minecart station!
I've thought of changing the code so that Minecraft and the script are using the same name for the world (right now Minecraft only sees the world name 'world' regardless of what the script thinks the world name is), but the change needs to happen in a few places. For instance, when first starting the server, it checks to make sure that the server.properties file exists, and it defaults to using a world name of 'world' if it doesn't. As far as I know, the only reason you should actually hit an issue here is if you started using this script with a previously running server, and in that case you would have to modify your config anyway. At this point, I'm a bit loathe to change it, but it is a probably a good idea in the long run. The problem is, this script has an existing user-base, so I'll either have to add code to update the old way to the new way of doing things, or break old configurations. Neither option is ideal, hence my reluctance to do this right now. =/
Edit: I went ahead and made this change. The script should hopefully update any old configurations.
Thanks for the great script. I have it running (mainly).. but I had a few issues.
My system: Ubuntu 9.10. I had the other script running with dated backups as a bash script if that makes a difference.
1. wont' download new c10t bin. (can't find an error)
But I just placed the bin in the correct dir
2. Backup places a oddly named .gz file into the correct dir. I take it that my system doesn't like the date code you use.
Also it looks like i have my working dirs a bit different. I tried to edit it but maybe there is something missing. (ie. It seems to me that your worlds are in /minecraft_server/worlds/world/world
Any suggestions would be greatly appreciated.
Cheers,
d
Try the most recent version of the script and let me know if you are still having the same problems. I've made a few changes that might clean things up for you.
If you are still having issues, let me know what the output from the following commands are:
The current code tells Minecraft to load the world files located in /home/minecraft/worlds/alpha/alpha if the world's name is 'alpha'. The first alpha denotes the world name that the script sees, the second is actually the level-name in the server.properties file. Old versions of the script told Minecraft that the level-name was 'world', regardless of what the script thought the world name was (ie /home/minecraft/worlds/alpha/world), but I found this slightly confusing myself and was not surprised to see issues in this thread. I just changed it so that the world name that the script sees is the same as the level-name that Minecraft sees. The double alpha in the directory name is still required to keep the Minecraft server files for each world separate from one another easily (and keep the server itself happy). I hope this explains your last question.
Thanks for replying. It didn't make a difference. I am not sure what I am doing wrong here. The only change I have made is the folders. I found that kept everything in a slightly different structure. (If you think that is an issue I can explain it)
Anything else I can try? I guess there will be a web interface for this sort of thing soon. (bukket? or something). But I like the ability to SSH in and make these simple changes...
Thanks again,
d
Ok, that explains the issue with updating c10t. My box returns 'x86_64' with the uname command, and I assumed that 32 bit boxes returned 'x86'. I'll make some changes to fix this one.
As far as the issue with the backups, give me a directory listing or an example of the failed backup names. It should look like 'fullBackup-alpha-2011-01-12-21:41:55.tar.gz'. Your date command appears to function the same as mine, so I'm not sure what's going on here. Maybe I should simplify the names by removing the time stamp, although I like being able to have multiple backups in a single day. I'll try to think of a possible work around while I wait for your reply on this one.
As for my directory structure:
Here are some examples (copy/pasted from my script)
And my backups end up looking like:
FFBDKZ~L.GZ
But within those .gz files are the correct files.
Thanks again. :smile.gif:
d
I posted a new version of the script that should, hopefully, fix the c10t update issue. Let me know if it doesn't (you can delete the old directory and see if it downloads a new one).
The backup issue confuses me. First off, are the backups looking like that on your Ubuntu box? Windows? What file system is being used? Can you give me a full directory listing of the backup directory?
My guess is it has something to do with the colons ":" in the file name, and that you are writing to a NTFS file system or something else that doesn't like that. I'll work out a better naming system for the backup files (maybe instead of the time, I'll just add a -1 -2 for multiple backups in the same day).
For the backups I do drop them on to a Samba share that I can see from my windows box. And when I ran a ls -la on the dir.. the names were correct.
That's good.. and bad.. :tongue.gif:
The other script I used (http://www.minecraftwiki.net/wiki/Server_startup_script) was creating readable file names. Do you see something in there that is different?
What did you change in the most recent script? I have to edit each dir line for every new one. :smile.gif: Would be quicker to just update the line(s) that you updated.
I will take a look thru it though. I might see the ones changed for c10t.
Thanks again for you help.
---Edit---
Ok, The c10t worked. Updated no problem.. I deleted the /c10t and everything. Thanks !!
for you.
d