Save coins when the server restarts? - minecraft

Moin I made my own script with coins. But when the server restarts the coins are set to 0 at each time someone has an idea how to set that that which can be saved. (Scripts not so long)
Here's the script:
command /coins:
aliases: coin
trigger:
send "&e&lEndless &7● &aDu hast &e%{coins::%player%}% &aCoins" to player
Command /pay [<player>] [<number>]:
trigger:
if arg-1 is set:
if arg-1 is not player:
if arg-2 is smaller than {coins::%player%}:
remove arg-2 from {coins::%player%}
add arg-2 to {coins::%arg-1%}
send " &7Du hast &e%arg-2% Coins &7an &a%arg-1% &7gesendet!" to player
send " &7Du hast &e%arg-2% Coins &7von &a%player% &7erhalten!" to arg-1
stop
else if arg-2 is bigger than {coins::%player%}:
send "&e&lEndless &7● &cDu hast nicht genügend &eCoins"
stop
else if arg-1 is player:
send "&e&lEndless &7● &7Du kannst dir selber kein Geld geben!"
stop
else if arg-1 is not set:
send "&e&lEndless &7● &7Nutze&8: &e/pay <Spieler> <Anzahl>"
stop
on first join:
set {coins::%player%} to 2000
every 1 tick:
loop all players:
if {coins::%loop-player%} is below 0:
set {coins::%loop-player%} to 0
if {coins::%loop-player%} is not set:
set {coins::%loop-player%} to 0
command /removecoins [<player>] [<number>]:
permission: coins.remcoins
permission message: &e&lEndless &7● &c&lKeine Erlaubnis
trigger:
if arg-1 is set:
if arg-2 is a number:
remove arg-2 from {coins::%arg-1%}
send "&e&lEndless &7● &7%arg-1% wurden &e%arg-2% Coins &7abgezogen!"
stop
if arg-1 is not set:
send "&e&lEndless &7● &7Bitte gebe einen Spieler und Beitrag an!"
stop
command /admin [<player>] [<number>]:
permission: coins.remcoins
permission message: &e&lEndless &7● &c&lKeine Erlaubnis
trigger:
if arg-1 is set:
if arg-2 is a number:
remove arg-2 from {coins::%arg-1%}
stop
if arg-1 is not set:
stop
Command /addcoins [<player>] [<number>]:
permission: coins.givecoins
permission message: &e&lEndless &7● &c&lKeine Erlaubnis
trigger:
if arg-1 is set:
if arg-2 is a number:
add arg-2 to {coins::%arg-1%}
send "&e&lEndless &7● &7%arg-1% hat &e%arg-2% Coins &7erhalten!"
stop
else if arg-2 is not a number:
send "&e&lEndless &7● &7Das ist keine Anzahl!"
if arg-1 is not set:
send "&e&lEndless &7● &7Bitte gebe einen Spieler und Beitrag an!"
stop

Maybe you can try to use a mysql database and save coins in there.
then you can just create Statements and store them secure in a database, even if the servers are offline.
try this to connect:
Connection conn = null;
try {
// db parameters
String url = "jdbc:mysql://localhost:3306/mysqljdbc";
String user = "root";
String password = "secret";
// create a connection to the database
conn = DriverManager.getConnection(url, user, password);
// more processing here
// ...
} catch(SQLException e) {
System.out.println(e.getMessage());
} finally {
try{
if(conn ! null)
conn.close()
}catch(SQLException ex){
System.out.println(ex.getMessage())
}
}

on server stop:
save-all
set {coins ::%players%} to "%{coins ::%players%}%"
You need to make it make sure it saves it and the game it will set all online players coins to what they have to try and save it also saves the game to save skript and the coins on the server stop.

Related

Zeek Scripting "Error field missing value"

I'm trying to write a Zeek script to divide the dns traffic into two log files (query and reply)
The error is "Field missing value" for the code $TTL=c$dns$TTLs in dns_query_reply event.
I don't understand the reason for this error since the dns.log file correctly contains the value.
The code is as follows:
module DnsFeatureExtractor;
export{
redef enum Log::ID += {QueryDNS};
redef enum Log::ID += {ReplyDNS};
type InfoQuery: record{
uid: string &log;
id: conn_id &log;
domain: string &log &optional;
query_type: string &log &optional;
timestamp: time &log;
};
type InfoReply: record{
uid: string &log;
id: conn_id &log;
response_code: count &log &optional;
TTL: vector of interval &log &optional;
resolved_IP: vector of string &log &optional;
timestamp: time &log;
};
}
event zeek_init(){
Log::create_stream(QueryDNS, [$columns=InfoQuery, $path="QueryDNS"]);
Log::create_stream(ReplyDNS, [$columns=InfoReply, $path="ReplyDNS"]);
}
event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count){
local name_qtype = DNS::query_types[qtype];
local rec: DnsFeatureExtractor::InfoQuery = [$uid=c$uid, $id=c$id, $domain=query, $query_type=name_qtype, $timestamp=c$start_time];
Log::write(DnsFeatureExtractor::QueryDNS, rec);
}
event dns_query_reply(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count){
local rec_r: DnsFeatureExtractor::InfoReply = [$uid=c$uid, $id=c$id, $response_code=msg$rcode, $TTL=c$dns$TTLs, $resolved_IP=c$dns$answers, $timestamp=c$start_time];
Log::write(DnsFeatureExtractor::ReplyDNS, rec_r);
}
This one's subtle: you're seeing an ordering problem. The dns_query_reply event handler is invoked before that of the event that actually populates the TTLs (such as dns_A_reply).
The c$dns fields in question get populated in the DNS::do_reply hook, so your best bet is to ensure you add to the hook. If you use the default priority, it'll run after the one that populates the fields. Try this instead of the dns_query_reply handler:
hook DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) {
local rec_r: DnsFeatureExtractor::InfoReply = [$uid=c$uid, $id=c$id, $response_code=msg$rcode, $TTL=c$dns$TTLs, $resolved_IP=c$dns$answers, $timestamp=c$start_time];
Log::write(DnsFeatureExtractor::ReplyDNS, rec_r);
}
Note that you're still dealing with optional record values, so it's possible that despite the above you still don't see all field values. To guard against that, you could check whether the optional values are actually defined, and copy them over only in that case:
hook DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string)
{
local rec_r: DnsFeatureExtractor::InfoReply = [$uid=c$uid, $id=c$id, $response_code=msg$rcode, $timestamp=c$start_time];
if ( c$dns?$TTLs )
rec_r$TTL = c$dns$TTLs;
if ( c$dns?$answers )
rec_r$resolved_IP = c$dns$answers;
Log::write(DnsFeatureExtractor::ReplyDNS, rec_r);
}

Cro WebSocket client doesn't see when the server goes out

The client program below receives messages from a WebSocket server.
It doesn't send any messages.
CLIENT
use v6;
use Cro::WebSocket::Client;
constant WS-URL = 'ws://localhost:20000/status';
constant TIMEOUT-TO-CONNECT = 5; # seconds
my $timeout;
my $connection-attempt;
await Promise.anyof(
$connection-attempt = Cro::WebSocket::Client.connect(WS-URL),
$timeout = Promise.in(TIMEOUT-TO-CONNECT));
if $timeout.status == Kept
{
say "* could not connect to server in ', TIMEOUT-TO-CONNECT, ' seconds";
exit 1;
}
if $connection-attempt.status != Kept
{
my $cause = $connection-attempt.cause;
say '"* error when trying to connect to server';
say '"* --------------------------------------';
# $cause is a long string, how do we get a simple numeric code ?
say $cause;
say '"* ======================================';
exit 1;
}
my $connection = $connection-attempt.result;
my $peer = 'localhost:20000';
say '* connected with ', $peer;
react
{
whenever $connection.messages -> $message
{
my $body = await $message.body;
say '* received message=[' ~ $body ~ '] from server';
LAST { say '* LAST'; done; }
QUIT { default { say '* QUIT'; done; }}
}
CLOSE { say '* CLOSE: leaving react block';}
} # react
SERVER
use Cro::HTTP::Router;
use Cro::HTTP::Server;
use Cro::HTTP::Router::WebSocket;
my $application =
route
{
get -> 'status'
{
web-socket -> $incoming
{
my $counter = 0;
my $timer = Supply.interval(1);
supply
{
whenever $incoming -> $thing
{
LAST { note '* LAST: client connection was closed'; done; }
QUIT { default { note '* QUIT: error in client connection'; done; } }
}
whenever $timer
{
$counter++;
say '* sending message ', $counter;
emit $counter.Str;
}
CLOSE { say '* CLOSE: leaving supply block'; }
} # supply
} #incoming
} # get -> status
}
my $server = Cro::HTTP::Server.new: :port(20000), :$application;
$server.start;
say '* serving on port 20000';
react whenever signal(SIGINT)
{
$server.stop;
exit;
}
Now, when the server goes out (say, by Ctrl+C) the client sees nothing.
Setting CRO_TRACE=1 in the client gives this:
TRACE(anon 2)] Cro::WebSocket::MessageParser EMIT WebSocket Message - Text
* received message=[4] from server
[TRACE(anon 1)] Cro::TCP::Connector DONE
[TRACE(anon 2)] Cro::WebSocket::FrameParser DONE
[TRACE(anon 2)] Cro::WebSocket::MessageParser DONE
[TRACE(anon 1)] Cro::HTTP::ResponseParser DONE
^C
The client showed nothing more (and then I cancelled it).
So, the question is: how should the client deal with this scenario ?
UPDATE
Edited the question, now showing the server code
Also, I'm in Fedora 28.
When I first cancel the server, netstat shows
$ netstat -ant | grep 20000
tcp6 0 0 ::1:20000 ::1:56652 TIME_WAIT
$
Tcpdump shows
IP6 ::1.20000 > ::1.56652: Flags [F.], seq 145, ack 194, win 350, options [nop,nop,TS val 1476681452 ecr 1476680552], length 0
IP6 ::1.56652 > ::1.20000: Flags [F.], seq 194, ack 146, win 350, options [nop,nop,TS val 1476681453 ecr 1476681452], length 0
IP6 ::1.20000 > ::1.56652: Flags [.], ack 195, win 350, options [nop,nop,TS val 1476681453 ecr 1476681453], length 0
It seems the last ACK from the client to the server is missing, I guess the client didn't close the connection.
Also, I'm curious as to why Cro chooses to work with IPv6 by default.
This is a bug that has been fixed since this question was posted, but I'm leaving an answer because of this part of the question that may confuse people when dealing with networking in Raku:
Also, I'm curious as to why Cro chooses to work with IPv6 by default.
localhost will resolve to an IPv6 address first if that's what the first address for localhost in your hosts file is. As of writing, IO::Socket::Async (which Cro uses internally) only allows PF_UNSPEC to be specified as a family, and the only address that will ever used from the results of hostname resolution is the first one in the list of addresses received. This will be changed at some point in the future as part of the work for my IP6NS grant and a problem solving issue to improve how DNS is handled, but for now, if you want to use IPv4/IPv6 only, you should specify 127.0.0.1/::1 instead of using localhost (or whichever addresses your machine resolves it to if they're different).

expect - ssh - two possible passwords - or how to jump of expect block and still use send clausule

first I need to say that I am avare of using public and private keys but this did not solve my problem. Also I am aware that I can use two scripts (one with password1 and second with password2) and run them two times but I am wondering why following did not works. I am trying to make expect script that will connect through ssh and check if one of two passwords are correct. For this I am checking exit codes of script:
0 - password1 was correct
1 - password2 was correct
2,3,4,5,6 - some other exit codes, insipred by this post: expect send weird
constructions
There can be more possible login prompt on remote machine and I would like to make this script as generic as possible, so I cannot rely on the login prompt string. So far I have this code:
#!/usr/local/bin/expect
set username "username";
set remote_server "machine";
set password1 "badpassword";
set password2 "goodpassword";
set timeout 5;
set pretype 0;
set retcode 0;
if { $pretype == 0 } {
spawn ssh -q ${username}#${remote_server}
expect {
"no)?" { send "yes\r"; }
"denied" {
puts "Can't login to $remote_server. Check username and password\n";
set retcode 2;
}
"telnet:" {
puts "Can't connect to $remote_server via SSH or Telnet. Something went definitely wrong\n";
set retcode 3;
}
"failed" {
puts "Host $remote_server exists. Check ssh_hosts file\n";
set retcode 4;
}
timeout {
puts "Timeout problem. Host $remote_server doesn't respond\n";
set retcode 5;
}
"refused" {
puts "Host $remote_server refused to SSH. That is insecure.\n";
set retcode 6;
}
"assword:" { set pretype 1; send "${password1}\r"; }
}
} else {
expect{
"assword:" { send "${password2}\r"; exit 1; }
timeout { exit 0; }
}
}
The idea behind this is following: if I type wrong password I will have second opportunity to type correct one. So If I type wrong password first time my script should continue in else branch (because I set pretype to 1). Here I will expecting prompt for entering password again. So I will send second password and exit with code 1 (password2 was OK). If the timeout in else branch expires (the "password:" string did not match), most probably I already have login prompt, so script will exit with code 0 (password1 was OK). But this did not working, and if I ran this inside debugger the last line I saw was:
send: sending "badpassword\r\r" to { exp4 }
I do not know why this happens, but seems that script never reaches the else branch. Thank you very much
set pretype 1 in the if block cannot make it go to the else block again. No programming languages would do this. You need something like a loop (using while or exp_continue) here.
Following is an example:
#!/usr/bin/expect
set passwords { bad1 bad2 bad3 good }
spawn ssh -o PreferredAuthentications=keyboard-interactive \
-o NumberOfPasswordPrompts=[llength $passwords] root#tree
set try 0
expect {
"Password: " {
if { $try >= [llength $passwords] } {
send_error ">>> wrong passwords\n"
exit 1
}
send [lindex $passwords $try]\r
incr try
exp_continue
}
"bash-4.2" {
interact
}
timeout {
send_error ">>> timed out\n"
exit 1
}
}

Do I need an SSL installed to implement DKIM

I'm using open-dkim and phpmailer to sign my outgoing mail, I have my keys installed, and showing as valid, and the mail script is working, but I get one openSSL error that's holding up the process:
Warning: openssl_sign() [function.openssl-sign]: supplied key param cannot be coerced into a private key in /usr/share/php/class.phpmailer.php on line 2221
I know nothing of openssl, but my first thought was that this domain does not have an SSL installed, so maybe that's required with DKIM?? If so, is it as simple as installing the new SSL as usual, or do I have to relate the public/private keys to the SSL somehow?
Thanks
full script if needed:
<?
require_once("class.phpmailer.php");
$mailer = new PHPMailer();
$mailer->IsSMTP();
$mailer->Host = 'mail.domain.com';
$mailer->SMTPAuth = true;
$mailer->Username = 'info#domain.com';
$mailer->Password = 'pass';
$mailer->FromName = 'info#domain.com';
$mailer->From = 'info#domain.com';
$mailer->AddAddress('test#gmail.com','first last');
$mailer->Subject = 'Testing DKIM';
$mailer->DKIM_domain = 'domain.com';
$mailer->DKIM_private = 'private.txt';
$mailer->DKIM_selector = 'default'; //this effects what you put in your DNS record
$mailer->DKIM_passphrase = '';
$mailer->Body = 'this is just an email test';
if(!$mailer->Send())
{
echo "Message was not sent";
echo "Mailer Error: " . $mailer->ErrorInfo;
exit;
} else {
echo "Message Sent!";
}
?>
The answer was two parts:
1) no, you do not apparently need a traditional SSL installed to use DKIM
2) my error was due to copying my private key from an RTF document which added extra characters. I copied it into dreamweaver, stripped the extra characters, and I'm now receiving sign email from my server

Enter password multiple times

I am running an application, which prompts for a password of the user about a dozen times :-(
I tried using expect to circumvent this issue, and make it run in auto mode, but am unable to get over the issue of the multiple times password, which is not exactly static. Sometimes it asks 4-5 times and sometime around 9-10 times.
Is there a better solution to the problem than what I have given below:
spawn myApp [lindex $argv 0]
expect " password: $"
send "$password\r"
expect {
" password: $" send "$password\r"
"^Rollout Done "
"^Rollout Updated "
}
With the above solution, I have only been able to catch the password twice and then manually start entering for the rest of the time, is there a loop possible with the password?
Look up the exp_continue command -- it prevents the current [expect] command from returning, so it can find any subsequent password prompts.
spawn myApp [lindex $argv 0]
expect {
-re { password: $} {
send "$password\r"
exp_continue
}
-re {^Rollout (?:Done|Updated) }
}
If you want the user to enter the password, rather than storing it in plain text in the script, see How can I make an expect script prompt for a password?
Expect can use loops -- it is just TCL with some added commands I believe. So just do
set found 0
while {$found < 1}
{
expect {
" password: $" send "$password\r"
"^Rollout Done " set found 1
"^Rollout Updated " set found 1
}
}