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.6 by root, Tue May 4 21:45:42 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 cf::async {
87 my $guard = cf::lock_acquire "highscore:check"; 84 my $guard = cf::lock_acquire "highscore";
88 85
89 # load hiscore, patch, save hiscore 86 cf::get_slot 0.01, 0, "highscore check";
90 my $hiscore = load_hiscore;
91 87
92 cf::get_slot 0.01, 0, "highscore check"; 88 my ($pre, $ins, $save);
93 89
94 my ($pre, $ins, $save); 90 pop @$HIGHSCORE while @$HIGHSCORE > $HIGHSCORE_ENTRIES;
95 91
96 pop @$hiscore while @$hiscore > $HIGHSCORE_ENTRIES; 92 # find previous entry, and new position
97 93
98 # find previous entry, and new position 94 for (0 .. $#$HIGHSCORE) {
95 $pre //= $_ if $HIGHSCORE->[$_][0] eq $score->[0];
96 $ins //= $_ if $HIGHSCORE->[$_][2] < $score->[2];
97 }
98 cf::cede_to_tick; # we need an "interruptible" block...
99 99
100 for (0 .. $#$hiscore) { 100 my $msg;
101 $pre //= $_ if $hiscore->[$_][0] eq $score->[0];
102 $ins //= $_ if $hiscore->[$_][2] < $score->[2];
103 }
104 cf::cede_to_tick; # we need an "interruptible" block...
105 101
106 my $msg;
107
108 if (defined $pre) { 102 if (defined $pre) {
109 # we are already in the list 103 # we are already in the list
110 if ($hiscore->[$pre][2] < $score->[2]) { 104 if ($HIGHSCORE->[$pre][2] < $score->[2]) {
111 $msg = "T<You beat your last score!>\n\n" 105 $msg = "T<You beat your last score!>\n\n"
112 . $SEP
113 . $HEADER
114 . $SEP
115 . (fmt $ins, $score)
116 . (fmt $pre, $hiscore->[$pre])
117 . $SEP;
118
119 splice @$hiscore, $pre, 1;
120 splice @$hiscore, $ins, 0, $score;
121 $save = 1;
122 } else {
123 $msg = "T<You did not beat your last score.>\n\n"
124 . $SEP
125 . $HEADER
126 . $SEP
127 . (fmt $pre , $hiscore->[$pre])
128 . (fmt undef, $score)
129 . $SEP;
130 }
131 } elsif (defined $ins or @$hiscore < $HIGHSCORE_ENTRIES) {
132 $ins //= @$hiscore;
133
134 $msg = "T<You entered the highscore list!>\n\n"
135 . $SEP 106 . $SEP
136 . $HEADER 107 . $HEADER
137 . $SEP 108 . $SEP
138 . (fmt $ins, $score) 109 . (fmt $ins, $score)
110 . (fmt $pre, $HIGHSCORE->[$pre])
139 . $SEP; 111 . $SEP;
140 112
113 splice @$HIGHSCORE, $pre, 1;
141 splice @$hiscore, $ins, 0, $score; 114 splice @$HIGHSCORE, $ins, 0, $score;
142 $save = 1; 115 $save = 1;
143 } else { 116 } else {
144 $msg = "T<You did not enter the highscore list.>\n\n" 117 $msg = "T<You did not beat your last score.>\n\n"
145 . $SEP 118 . $SEP
146 . $HEADER 119 . $HEADER
147 . $SEP 120 . $SEP
148 . (fmt -1 + (scalar @$hiscore), $hiscore->[-1]) 121 . (fmt $pre , $HIGHSCORE->[$pre])
149 . (fmt undef, $score) 122 . (fmt undef, $score)
150 . $SEP; 123 . $SEP;
151 } 124 }
125 } elsif (defined $ins or @$HIGHSCORE < $HIGHSCORE_ENTRIES) {
126 $ins //= @$HIGHSCORE;
152 127
153 cf::info $msg;#d# remove once working stable 128 $msg = "T<You entered the highscore list!>\n\n"
129 . $SEP
130 . $HEADER
131 . $SEP
132 . (fmt $ins, $score)
133 . $SEP;
154 134
155 $ob->send_msg ($SCORE_CHANNEL => $msg, cf::NDI_CLEAR); 135 splice @$HIGHSCORE, $ins, 0, $score;
136 $save = 1;
137 } else {
138 $msg = "T<You did not enter the highscore list.>\n\n"
139 . $SEP
140 . $HEADER
141 . $SEP
142 . (fmt -1 + (scalar @$HIGHSCORE), $HIGHSCORE->[-1])
143 . (fmt undef, $score)
144 . $SEP;
145 }
156 146
147 cf::info $msg;#d# remove once working stable
148
149 $ob->send_msg ($SCORE_CHANNEL => $msg, cf::NDI_CLEAR);
150
157 if ($save) { 151 if ($save) {
158 save_hiscore $hiscore 152 save_highscore
159 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 };
160 } 169 }
161 }; 170 }
162} 171}
163 172

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines