ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/highscore.ext
(Generate patch)

Comparing deliantra/server/ext/highscore.ext (file contents):
Revision 1.7 by root, Sun May 9 22:51:13 2010 UTC vs.
Revision 1.10 by root, Fri Feb 3 03:59:17 2012 UTC

1#! perl 1#! perl
2 2
3use Fcntl (); 3use Fcntl ();
4use Coro::AIO; 4use Coro::AIO;
5 5
6our $HIGHSCORE_ENTRIES = $cf::CFG{highscore_entries} || 1000; 6CONF HIGHSCORE_ENTRIES = 1000
7CONF EXPORT_HIGHSCORE = "www.deliantra.net/highscore.json"
8
9our $HIGHSCORE;
7 10
8# [name, title, exp, killer, where, hp, sp, gp, uuid] 11# [name, title, exp, killer, where, hp, sp, gp, uuid]
9 12
10sub load_hiscore() { 13sub load_highscore() {
11# if (0 <= aio_load "$cf::LOCALDIR/hiscore.json", my $json) { 14# if (0 <= aio_load "$cf::LOCALDIR/hiscore.json", my $json) {
12# return JSON::XS::decode_json $json; 15# return JSON::XS::decode_json $json;
13# } 16# }
14 17
15 # try to convert old highscore file 18 # try to convert old highscore file
19 } 22 }
20 23
21 return []; 24 return [];
22} 25}
23 26
24sub save_hiscore($) { 27sub reload {
25 my ($hiscore) = @_; 28 my $lock = cf::lock_acquire "highscore";
26 29
27 my $fh = aio_open "$cf::LOCALDIR/highscore~", Fcntl::O_WRONLY | Fcntl::O_CREAT | Fcntl::O_TRUNC, 0644 30 cf::async_ext {
28 or return; 31 $lock;
29 32
30 $hiscore = join "", map "$_\n", map +(join ":", @$_), @$hiscore; 33 $HIGHSCORE = load_highscore;
34 };
35}
31 36
32 length $hiscore == aio_write $fh, 0, (length $hiscore), $hiscore, 0 37cf::post_init {
33 or return; 38 reload;
39};
34 40
35 # always fsync - this file is important 41sub save_highscore() {
36 aio_fsync $fh 42 my $highscore = join "", map "$_\n", map +(join ":", @$_), @$HIGHSCORE;
37 and return;
38 43
39 close $fh 44 cf::replace_file "$cf::LOCALDIR/highscore", $highscore, 1;
40 or return;
41
42 aio_rename "$cf::LOCALDIR/highscore~", "$cf::LOCALDIR/highscore"
43 and return;
44
45 aio_pathsync "$cf::LOCALDIR";
46
47 cf::trace "saved highscore file.\n"; 45 cf::trace "saved highscore file.\n";
48 46
49 1 47 1
50} 48}
51 49
81 $ob->stats->maxgrace, 79 $ob->stats->maxgrace,
82 $ob->uuid, 80 $ob->uuid,
83 int AE::now, 81 int AE::now,
84 ]; 82 ];
85 83
86 my $guard = cf::lock_acquire "highscore:check"; 84 my $guard = cf::lock_acquire "highscore";
87
88 # load hiscore, patch, save hiscore
89 my $hiscore = load_hiscore;
90 85
91 cf::get_slot 0.01, 0, "highscore check"; 86 cf::get_slot 0.01, 0, "highscore check";
92 87
93 my ($pre, $ins, $save); 88 my ($pre, $ins, $save);
94 89
95 pop @$hiscore while @$hiscore > $HIGHSCORE_ENTRIES; 90 pop @$HIGHSCORE while @$HIGHSCORE > $HIGHSCORE_ENTRIES;
96 91
97 # find previous entry, and new position 92 # find previous entry, and new position
98 93
99 for (0 .. $#$hiscore) { 94 for (0 .. $#$HIGHSCORE) {
100 $pre //= $_ if $hiscore->[$_][0] eq $score->[0]; 95 $pre //= $_ if $HIGHSCORE->[$_][0] eq $score->[0];
101 $ins //= $_ if $hiscore->[$_][2] < $score->[2]; 96 $ins //= $_ if $HIGHSCORE->[$_][2] < $score->[2];
102 } 97 }
103 cf::cede_to_tick; # we need an "interruptible" block... 98 cf::cede_to_tick; # we need an "interruptible" block...
104 99
105 my $msg; 100 my $msg;
106 101
107 if (defined $pre) { 102 if (defined $pre) {
108 # we are already in the list 103 # we are already in the list
109 if ($hiscore->[$pre][2] < $score->[2]) { 104 if ($HIGHSCORE->[$pre][2] < $score->[2]) {
110 $msg = "T<You beat your last score!>\n\n" 105 $msg = "T<You beat your last score!>\n\n"
111 . $SEP 106 . $SEP
112 . $HEADER 107 . $HEADER
113 . $SEP 108 . $SEP
114 . (fmt $ins, $score) 109 . (fmt $ins, $score)
115 . (fmt $pre, $hiscore->[$pre]) 110 . (fmt $pre, $HIGHSCORE->[$pre])
116 . $SEP; 111 . $SEP;
117 112
118 splice @$hiscore, $pre, 1; 113 splice @$HIGHSCORE, $pre, 1;
119 splice @$hiscore, $ins, 0, $score; 114 splice @$HIGHSCORE, $ins, 0, $score;
120 $save = 1; 115 $save = 1;
121 } else { 116 } else {
122 $msg = "T<You did not beat your last score.>\n\n" 117 $msg = "T<You did not beat your last score.>\n\n"
123 . $SEP 118 . $SEP
124 . $HEADER 119 . $HEADER
125 . $SEP 120 . $SEP
126 . (fmt $pre , $hiscore->[$pre]) 121 . (fmt $pre , $HIGHSCORE->[$pre])
127 . (fmt undef, $score) 122 . (fmt undef, $score)
128 . $SEP; 123 . $SEP;
129 } 124 }
130 } elsif (defined $ins or @$hiscore < $HIGHSCORE_ENTRIES) { 125 } elsif (defined $ins or @$HIGHSCORE < $HIGHSCORE_ENTRIES) {
131 $ins //= @$hiscore; 126 $ins //= @$HIGHSCORE;
132 127
133 $msg = "T<You entered the highscore list!>\n\n" 128 $msg = "T<You entered the highscore list!>\n\n"
134 . $SEP 129 . $SEP
135 . $HEADER 130 . $HEADER
136 . $SEP 131 . $SEP
137 . (fmt $ins, $score) 132 . (fmt $ins, $score)
138 . $SEP; 133 . $SEP;
139 134
140 splice @$hiscore, $ins, 0, $score; 135 splice @$HIGHSCORE, $ins, 0, $score;
141 $save = 1; 136 $save = 1;
142 } else { 137 } else {
143 $msg = "T<You did not enter the highscore list.>\n\n" 138 $msg = "T<You did not enter the highscore list.>\n\n"
144 . $SEP 139 . $SEP
145 . $HEADER 140 . $HEADER
146 . $SEP 141 . $SEP
147 . (fmt -1 + (scalar @$hiscore), $hiscore->[-1]) 142 . (fmt -1 + (scalar @$HIGHSCORE), $HIGHSCORE->[-1])
148 . (fmt undef, $score) 143 . (fmt undef, $score)
149 . $SEP; 144 . $SEP;
150 } 145 }
151 146
152 cf::info $msg;#d# remove once working stable 147 cf::info $msg;#d# remove once working stable
153 148
154 $ob->send_msg ($SCORE_CHANNEL => $msg, cf::NDI_CLEAR); 149 $ob->send_msg ($SCORE_CHANNEL => $msg, cf::NDI_CLEAR);
155 150
156 if ($save) { 151 if ($save) {
157 save_hiscore $hiscore 152 save_highscore
158 or die "unable to write highscore file: $!"; 153 or die "unable to write highscore file: $!";
154
155 if (defined $EXPORT_HIGHSCORE) {
156 cf::get_slot 0.05, 0, "highscore export";
157
158 my $rank;
159 my @highscore = map {
160 my ($name, $title, $exp, $killer, $map, $hp, $sp, $grace) = @$_;
161 [++$rank, $name, $title, (cf::exp_to_level $exp), $exp, $killer, $map, $hp, $sp, $grace]
162 } @$HIGHSCORE;
163
164 cf::replace_file $EXPORT_HIGHSCORE, cf::encode_json {
165 version => 1,
166 date => $cf::NOW,
167 data => \@highscore,
168 };
169 }
159 } 170 }
160} 171}
161 172

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines