Skip to content

Commit c89c428

Browse files
2 parents c46df5c + b016953 commit c89c428

File tree

6 files changed

+137
-36
lines changed

6 files changed

+137
-36
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ If you are a sampctl user
7474
* `callback[]` - callback to execute after hashing
7575
* `input[]` - text to compare with hash
7676
* `hash[]` - hash to compare with text
77-
77+
* `args` - custom arguments
78+
7879
**Example**
7980
```Pawn
8081
main(){

include/samp_bcrypt.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ bcrypt_verify(playerid,callback[],input[],hash[])
4444
`callback[]` - callback to execute after hashing
4545
`input[]` - text to compare with hash
4646
`hash[]` - hash to compare with text
47+
`args` - custom arguments
4748
Example
4849
```
4950
main(){
@@ -61,7 +62,7 @@ bcrypt_verify(playerid,callback[],input[],hash[])
6162
}
6263
```
6364
*/
64-
native bcrypt_verify(playerid, const callback[], const input[], const hash[]);
65+
native bcrypt_verify(playerid, const callback[], const input[], const hash[],const args[] = "", {Float, _}:...);
6566
/*
6667
bcrypt_get_hash(dest[],size = sizeof(hash))
6768
Params

pawn-tests/test.pwn

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ Test:TestBcryptHash(){
1717
bcrypt_hash(0,"OnPassswordHash3","test",4,"issf",69,"hello","world",10.0);
1818

1919
}
20+
2021
Test:TestInvalidCustomArgs() {
2122
ASSERT(bcrypt_hash(0,"WontCall","test",4,"issf",69,"world",10.0)==0);
2223
ASSERT(bcrypt_hash(0,"WontCall","test",4,"issf",69,"world",10.0,1,1)==0);
2324
ASSERT(bcrypt_hash(0,"WontCall","test",4,"issf",69,"world",10.0,1,1)==0);
25+
26+
ASSERT(bcrypt_verify(0,"WontCall","test","test_hash","issf",69,"world",10.0)==0);
27+
ASSERT(bcrypt_verify(0,"WontCall","test","test_hash","issf",69,"world",10.0,1,1)==0);
28+
ASSERT(bcrypt_verify(0,"WontCall","test","test_hash","issf",69,"world",10.0,1,1)==0);
2429
}
2530

2631
forward OnPassswordHash(playerid);
@@ -49,6 +54,7 @@ public OnPassswordHash3(playerid,int1,str1[],str2[],Float:float1){
4954
printf("hash is %s",dest);
5055
bcrypt_verify(playerid,"OnPassswordVerifyInvalid","text",dest);
5156
bcrypt_verify(playerid,"OnPassswordVerifyValid","test",dest);
57+
bcrypt_verify(playerid,"OnPassswordVerifyValidWithArgs","test",dest,"issf",69,"hello","world",10.0);
5258
}
5359

5460
forward OnPassswordHash2(playerid);
@@ -60,13 +66,29 @@ public OnPassswordHash2(playerid){
6066
bcrypt_verify(playerid,"OnPassswordVerifyInvalid","text",dest);
6167
bcrypt_verify(playerid,"OnPassswordVerifyValid","test",dest);
6268
}
69+
6370
forward OnPassswordVerifyValid(playerid,bool:success);
6471
public OnPassswordVerifyValid(playerid,bool:success){
6572
printf("***OnPassswordVerifyValid");
6673
ASSERT(success == true);
6774
print("\nPASS!");
6875
}
6976

77+
forward OnPassswordVerifyValidWithArgs(playerid,bool:success,int1,str1[],str2[],Float:float1);
78+
public OnPassswordVerifyValidWithArgs(playerid,bool:success,int1,str1[],str2[],Float:float1){
79+
printf("***OnPassswordVerifyValidWithArgs");
80+
ASSERT(success == true);
81+
ASSERT(int1 == 69);
82+
new comp1 = strcmp("hello",str1);
83+
new comp2 = strcmp("world",str2);
84+
85+
ASSERT(int1 == 69);
86+
ASSERT(comp1 == 0);
87+
ASSERT(comp2 == 0);
88+
ASSERT(float1 == 10.0);
89+
print("\nPASS!");
90+
}
91+
7092
forward OnPassswordVerifyInvalid(playerid,bool:success);
7193
public OnPassswordVerifyInvalid(playerid,bool:success){
7294
printf("***OnPassswordVerifyInvalid");

src/internals.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@ pub enum ArgumentTypes {
66
Primitive(i32),
77
String(Vec<u8>),
88
}
9+
pub type VerifyParams = (i32, String, bool, Vec<ArgumentTypes>);
10+
pub type HashParams = (i32, String, String, Vec<ArgumentTypes>);
911
pub fn hash_verify(
10-
verify_sender: Option<Sender<(i32, String, bool)>>,
12+
verify_sender: Option<Sender<VerifyParams>>,
1113
playerid: i32,
1214
input: String,
1315
hash: String,
1416
callback: String,
17+
optional_args: Vec<ArgumentTypes>,
1518
) {
1619
match verify(&input, &hash) {
1720
Ok(success) => {
18-
let _ = verify_sender
19-
.as_ref()
20-
.unwrap()
21-
.send((playerid, callback, success));
21+
let _ =
22+
verify_sender
23+
.as_ref()
24+
.unwrap()
25+
.send((playerid, callback, success, optional_args));
2226
}
2327
Err(err) => {
2428
error!("{} => {:?}", callback, err);
@@ -27,7 +31,7 @@ pub fn hash_verify(
2731
}
2832

2933
pub fn hash_start(
30-
hash_sender: Option<Sender<(i32, String, String, Vec<ArgumentTypes>)>>,
34+
hash_sender: Option<Sender<HashParams>>,
3135
playerid: i32,
3236
input: String,
3337
callback: String,

src/natives.rs

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use samp::prelude::*;
88
impl super::SampBcrypt {
99
#[native(raw, name = "bcrypt_hash")]
1010
pub fn bcrypt_hash(&mut self, amx: &Amx, mut args: samp::args::Args) -> AmxResult<bool> {
11-
1211
let playerid = args.next::<i32>().ok_or(AmxError::Params)?;
1312
let callback = args
1413
.next::<AmxString>()
@@ -19,14 +18,14 @@ impl super::SampBcrypt {
1918
.ok_or(AmxError::Params)?
2019
.to_string();
2120
let cost = args.next::<u32>().ok_or(AmxError::Params)?;
22-
let mut format:Vec<u8> = Vec::new();
21+
let mut format: Vec<u8> = Vec::new();
2322

2423
if args.count() > 4 {
2524
if let Some(specifiers) = args.next::<AmxString>() {
2625
format = specifiers.to_bytes();
2726
}
2827
}
29-
28+
3029
if !format.is_empty() && format.len() != args.count() - 5 {
3130
error!(
3231
"The argument count mismatch expected :{} provided: {}.",
@@ -75,28 +74,70 @@ impl super::SampBcrypt {
7574
match self.hashes.front() {
7675
Some(hash) => {
7776
let mut dest = dest.into_sized_buffer(size);
78-
let _ = samp::cell::string::put_in_buffer(&mut dest, &hash);
77+
let _ = samp::cell::string::put_in_buffer(&mut dest, hash);
7978
Ok(true)
8079
}
8180
None => Ok(false),
8281
}
8382
}
8483

85-
#[native(name = "bcrypt_verify")]
86-
pub fn bcrypt_verify(
87-
&mut self,
88-
_: &Amx,
89-
playerid: i32,
90-
callback: AmxString,
91-
input: AmxString,
92-
hash: AmxString,
93-
) -> AmxResult<bool> {
94-
let callback = callback.to_string();
95-
let input = input.to_string();
96-
let hash = hash.to_string();
84+
#[native(raw, name = "bcrypt_verify")]
85+
pub fn bcrypt_verify(&mut self, amx: &Amx, mut args: samp::args::Args) -> AmxResult<bool> {
86+
let playerid = args.next::<i32>().ok_or(AmxError::Params)?;
87+
let callback = args
88+
.next::<AmxString>()
89+
.ok_or(AmxError::Params)?
90+
.to_string();
91+
let input = args
92+
.next::<AmxString>()
93+
.ok_or(AmxError::Params)?
94+
.to_string();
95+
let hash = args
96+
.next::<AmxString>()
97+
.ok_or(AmxError::Params)?
98+
.to_string();
99+
100+
let mut format: Vec<u8> = Vec::new();
101+
102+
if args.count() > 4 {
103+
if let Some(specifiers) = args.next::<AmxString>() {
104+
format = specifiers.to_bytes();
105+
}
106+
}
107+
108+
if !format.is_empty() && format.len() != args.count() - 5 {
109+
error!(
110+
"The argument count mismatch expected :{} provided: {}.",
111+
format.len(),
112+
args.count() - 5
113+
);
114+
return Ok(false);
115+
}
116+
97117
let sender = self.verify_sender.clone();
118+
let mut optional_args: Vec<ArgumentTypes> = Vec::new();
119+
120+
for specifiers in format {
121+
match specifiers {
122+
b'd' | b'i' | b'f' => {
123+
optional_args.push(ArgumentTypes::Primitive(
124+
*args.next::<Ref<i32>>().ok_or(AmxError::Params)?,
125+
));
126+
}
127+
b's' => {
128+
let argument: Ref<i32> = args.next().ok_or(AmxError::Params)?;
129+
let amx_str = AmxString::from_raw(amx, argument.address())?;
130+
optional_args.push(ArgumentTypes::String(amx_str.to_bytes()));
131+
}
132+
_ => {
133+
error!("Unknown specifier type {}", specifiers);
134+
return Ok(false);
135+
}
136+
}
137+
}
138+
98139
self.pool.execute(move || {
99-
hash_verify(sender, playerid, input, hash, callback);
140+
hash_verify(sender, playerid, input, hash, callback, optional_args);
100141
});
101142

102143
Ok(true)

src/plugin.rs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use crate::internals::ArgumentTypes;
1+
use crate::internals::{ArgumentTypes, HashParams, VerifyParams};
22
use log::{error, info};
33
use samp::amx::AmxIdent;
4-
use samp::exec_public;
54
use samp::plugin::SampPlugin;
65
use samp::prelude::*;
76
use std::collections::LinkedList;
@@ -11,10 +10,10 @@ use threadpool::ThreadPool;
1110
pub struct SampBcrypt {
1211
pub hashes: LinkedList<String>,
1312
pub pool: ThreadPool,
14-
pub hash_sender: Option<Sender<(i32, String, String, Vec<ArgumentTypes>)>>,
15-
pub hash_receiver: Option<Receiver<(i32, String, String, Vec<ArgumentTypes>)>>,
16-
pub verify_sender: Option<Sender<(i32, String, bool)>>,
17-
pub verify_receiver: Option<Receiver<(i32, String, bool)>>,
13+
pub hash_sender: Option<Sender<HashParams>>,
14+
pub hash_receiver: Option<Receiver<HashParams>>,
15+
pub verify_sender: Option<Sender<VerifyParams>>,
16+
pub verify_receiver: Option<Receiver<VerifyParams>>,
1817
pub amx_list: Vec<AmxIdent>,
1918
}
2019

@@ -71,10 +70,10 @@ impl SampPlugin for SampBcrypt {
7170
error!("*Cannot execute callback {:?}", callback);
7271
}
7372
if let Ok(index) = amx.find_public(&callback) {
74-
if let Ok(_) = amx.exec(index) {
73+
if amx.exec(index).is_ok() {
7574
executed = true;
7675
break;
77-
}
76+
}
7877
}
7978
}
8079
}
@@ -83,17 +82,50 @@ impl SampPlugin for SampBcrypt {
8382
}
8483
}
8584

86-
for (playerid, callback, success) in self.verify_receiver.as_ref().unwrap().try_iter() {
85+
for (playerid, callback, success, optional_args) in
86+
self.verify_receiver.as_ref().unwrap().try_iter()
87+
{
8788
let mut executed = false;
8889
for amx in &self.amx_list {
8990
if let Some(amx) = samp::amx::get(*amx) {
90-
let _ = exec_public!(amx, &callback, playerid, success);
91-
executed = true;
91+
let allocator = amx.allocator();
92+
93+
for param in optional_args.iter().rev() {
94+
match param {
95+
ArgumentTypes::Primitive(x) => {
96+
if amx.push(x).is_err() {
97+
error!("*Cannot execute callback {:?}", callback);
98+
}
99+
}
100+
ArgumentTypes::String(data) => {
101+
let buf = allocator.allot_buffer(data.len() + 1).unwrap();
102+
let amx_str = unsafe { AmxString::new(buf, data) };
103+
if amx.push(amx_str).is_err() {
104+
error!("*Cannot execute callback {:?}", callback);
105+
}
106+
}
107+
}
108+
}
109+
if amx.push(success).is_err() {
110+
error!("*Cannot execute callback {:?}", callback);
111+
}
112+
if amx.push(playerid).is_err() {
113+
error!("*Cannot execute callback {:?}", callback);
114+
}
115+
if let Ok(index) = amx.find_public(&callback) {
116+
if amx.exec(index).is_ok() {
117+
executed = true;
118+
break;
119+
}
120+
}
92121
}
93122
}
94123
if !executed {
95124
error!("*Cannot execute callback {:?}", callback);
96125
}
126+
if !executed {
127+
error!("*Cannot execute callback {:?}", callback);
128+
}
97129
}
98130

99131
self.hashes.clear();

0 commit comments

Comments
 (0)